根据我的理解,所有的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个页面上包含相同的代码。事实上,您再也不需要在站点的任何地方包含手动脚本标记。

我想这就是我问题的真正答案。


当前回答

步骤1。移除require_tree。在你的application。js和application。css中。

步骤2。编辑你的application.html。Erb(由rails默认)在布局文件夹。在以下标签中添加“params[:controller]”。

<%= stylesheet_link_tag    'application', params[:controller], media: 'all', 'data-turbolinks-track' => true %>

<%= javascript_include_tag 'application', params[:controller], 'data-turbolinks-track' => true %>

步骤3。在config/initializers/assets.rb中添加一个文件

%w( controller_one controller_two controller_three ).each do |controller|
  Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.js.coffee", "#{controller}.css", "#{controller}.scss"]
end

引用: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/

其他回答

我知道你已经回答了自己的问题,但还有另一种选择

基本上,您假设//= 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的回答有所帮助,并添加了一些细节。

另一种选择:要创建特定于页面或模型的文件,您可以在assets/javascripts/文件夹中创建目录。

assets/javascripts/global/
assets/javascripts/cupcakes
assets/javascripts/something_else_specific

你的主application.js清单文件可以配置为从global/加载它的文件。特定的页面或页面组可以有它们自己的清单,这些清单从它们自己的特定目录加载文件。Sprockets会自动将application.js加载的文件与特定于页面的文件结合起来,这使得这个解决方案可以工作。

这种技术也可以用于style_sheets/。

虽然你在这里有几个答案,我认为你的编辑可能是最好的选择。我们在团队中使用的一个设计模式是从Gitlab获得的,它就是Dispatcher模式。它的功能与您正在讨论的类似,但是页面名称是由rails在body标记中设置的。例如,在你的布局文件中,只包括(在HAML中):

%body{'data-page' => "#{controller}:#{action}" }

然后在javascripts文件夹中的dispatcher.js.coffee文件中只有一个闭包和一个switch语句,如下所示:

$ ->
  new Dispatcher()

class Dispatcher
  constructor: ->
    page = $('body').attr('data-page')
    switch page
      when 'products:index'
        new Products() 
      when 'users:login'
        new Login()

在单个文件(例如products.js.coffee或login.js.coffee)中,你所需要做的就是将它们封装在一个类中,然后将类符号全球化,这样你就可以在调度程序中访问它:

class Products
  constructor: ->
    #do stuff
@Products = Products

Gitlab有几个这样的例子,如果你好奇的话,你可能想要戳一下:)

这个问题在很久以前就被回答和接受了,但是我基于其中一些答案和我使用Rails 3+的经验提出了我自己的解决方案。

资产管道是甜蜜的。使用它。

首先,在你的application.js文件中,删除//= require_tree。

然后在你的application_controller中。Rb创建一个helper方法:

helper_method :javascript_include_view_js //Or something similar

def javascript_include_view_js
    if FileTest.exists? "app/assets/javascripts/"+params[:controller]+"/"+params[:action]+".js.erb"
        return '<script src="/assets/'+params[:controller]+'/'+params[:action]+'.js.erb" type="text/javascript"></script>'
    end
end

然后在你的application.html.erb布局文件中,在现有的javascript include中添加你的新helper,并以raw helper为前缀:

<head>
    <title>Your Application</title>
    <%= stylesheet_link_tag "application", :media => "all" %>
    <%= javascript_include_tag "application" %>
    <%= raw javascript_include_view_js %>
</head>

瞧,现在您可以使用与rails中其他地方相同的文件结构轻松创建特定于视图的javascript。简单地把你的文件放在app/assets/:namespace/:controller/action.js.erb!

希望这能帮助到其他人!

<%= javascript_include_tag params[:controller] %>