根据我的理解,所有的JavaScript都合并到一个文件中。Rails在添加//= require_tree时默认这样做。到你的application.js manifest文件的底部。
这听起来像是一个真正的救星,但我有点担心特定于页面的JavaScript代码。这段代码是否在每一页上执行?我想要的最后一件事是当我的所有对象只在1页上需要时,为每一页实例化它们。
此外,代码是否也有可能发生冲突?
还是在页面底部放置一个小的脚本标记,只调用一个执行页面javascript代码的方法?
你不再需要require.js了吗?
谢谢
编辑:我很感激所有的答案…我认为他们并没有真正解决问题。其中一些是关于样式的,似乎没有关联……其他人只是提到javascript_include_tag…我知道这是存在的(很明显…),但Rails 3.1的前进方式似乎是将所有JavaScript打包到一个文件中,而不是在每个页面的底部加载单个JavaScript。
我能想到的最好的解决方案是用id或类将某些特性包装在div标签中。在JavaScript代码中,只需检查id或类是否在页面上,如果在,则运行与之关联的JavaScript代码。这样,如果动态元素不在页面上,JavaScript代码就不会运行——即使它包含在由Sprockets打包的庞大application.js文件中。
我上面的解决方案的好处是,如果一个搜索框包含在100个页面中的8个页面上,那么它将只在这8个页面上运行。你也不需要在网站的8个页面上包含相同的代码。事实上,您再也不需要在站点的任何地方包含手动脚本标记。
我想这就是我问题的真正答案。
我把一些答案组合成:
应用助手:
module ApplicationHelper
def js_page_specific_include
page_specific_js = params[:controller] + '_' + params[:action]
if Rails.application.assets.find_asset(page_specific_js).nil?
javascript_include_tag 'application', 'data-turbolinks-track' => true
else
javascript_include_tag 'application', page_specific_js, 'data-turbolinks-track' => true
end
end
end
布局/ application.html.haml:
<!DOCTYPE html>
%html{lang: 'uk'}
%head
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
bla-bla-bla
= js_page_specific_include
bla-bla-bla
对于特定页面的js,您可以使用Garber-Irish解决方案。
所以你的Rails javascripts文件夹对于两个控制器(cars和users)是这样的:
javascripts/
├── application.js
├── init.js
├── markup_based_js_execution
├── cars
│ ├── init .js
│ ├── index.js
│ └── ...
└── users
└── ...
javascript是这样的:
// application.js
//=
//= require init.js
//= require_tree cars
//= require_tree users
// init.js
SITENAME = new Object();
SITENAME.cars = new Object;
SITENAME.users = new Object;
SITENAME.common.init = function (){
// Your js code for all pages here
}
// cars/init.js
SITENAME.cars.init = function (){
// Your js code for the cars controller here
}
// cars/index.js
SITENAME.cars.index = function (){
// Your js code for the index method of the cars controller
}
和markup_based_js_execution将包含用于UTIL对象的代码,在dom就绪的UTIL上。初始化执行。
别忘了把这个放到你的布局文件中:
<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">
我还认为最好使用类而不是data-*属性,以获得更好的特定于页面的css。正如Jason Garber所提到的:特定于页面的CSS选择器会非常尴尬(当你使用data-*属性时)
我希望这对你有所帮助。
我知道你已经回答了自己的问题,但还有另一种选择
基本上,您假设//= require_tree。是必需的。事实并非如此。请随意删除它。在我当前的应用程序中,第一个应用程序使用3.1。老实说,我已经做了三个不同的顶级JS文件。我的application.js文件只有
//= require jquery
//= require jquery_ujs
//= require_directory .
//= require_directory ./api
//= require_directory ./admin
通过这种方式,我可以创建子目录,其中包含自己的顶级JS文件,只包括我需要的内容。
关键是:
你可以删除require_tree——Rails允许你改变它所做的假设
application.js这个名字没有什么特别之处——assets/javascript子目录下的任何文件都可以包含带有//=的预处理指令
希望这对ClosureCowboy的回答有所帮助,并添加了一些细节。
我没有看到一个答案,真正把它放在一起,并为你铺开。因此,我将尝试把meleyal, sujal (la ClosureCowboy), Ryan回答的第一部分,甚至Gal关于Backbone.js的大胆陈述……以一种简短而清晰的方式把它们放在一起。谁知道呢,我甚至可能满足Marnen Laibow-Koser的要求。
例子编辑
资产javascripts / js应用程序。
//= require jquery
//= require jquery_ujs
//= require lodash.underscore.min
...
视图/布局/ application.html.erb
...
</footer>
<!-- Javascripts ================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<%= javascript_include_tag "application" %>
<%= yield :javascript %>
</body>
</html>
视图/ foo / index . html . erb
...
<% content_for :javascript do %>
<%= javascript_include_tag params[:controller] %>
<% end %>
资产javascripts / foo js。
//= require moment
//= require_tree ./foostuff
assets/javascripts/foostuff/foothis.js.coffee
alert "Hello world!"
简要描述
Remove //= require_tree . from application.js and list only the JS that each page shares.
The two lines shown above in application.html.erb tell the page where to include application.js and your page-specific JS.
The three lines shown above in index.html.erb tells your view to look for some page-specific JS and include it at a named yield region called ":javascript" (or whatever you want to name it). In this example, the controller is "foo" so Rails will attempt to include "foo.js" at the :javascript yield region in the application layout.
List your page-specific JS in foo.js (or whatever the controller is named). List common libraries, a tree, directories, whatever.
Keep your custom page-specific JS someplace where you can easily reference it apart from your other custom JS. In this example, foo.js requires the foostuff tree so put your custom JS there, such as foothis.js.coffee.
There are no hard rules here. Feel free to move things around and perhaps even create multiple yield regions of various names in various layouts if needed. This just shows one possible first step forward. (I don't do it exactly like this given our use of Backbone.js. I might also choose to drop foo.js down into a folder called foo instead of foostuff but haven't decided that yet.)
笔记
你可以用CSS和<%= stylesheet_link_tag params[:controller] %>做类似的事情,但这超出了问题的范围。
如果我在这里错过了一个明显的最佳实践,给我发个便条,我会考虑适应。Rails对我来说相当新鲜,老实说,到目前为止,我对它默认给企业开发带来的混乱以及普通Rails程序产生的所有流量并没有太大印象。