在Rails 3应用程序中添加特定于页面的JavaScript的最佳方法?

Bri*_*ong 157 javascript ruby-on-rails ruby-on-rails-3

Rails 3有一些不引人注目的JavaScript,非常酷.

但我想知道最好的方法是为特定页面添加额外的JavaScript.

例如,我之前可能做过的事情:

<%= f.radio_button :rating, 'positive', :onclick => "$('some_div').show();" %>
Run Code Online (Sandbox Code Playgroud)

我们现在可以用类似的东西使它不引人注目

<%= f.radio_button :rating, 'positive' %>

# then in some other file
$('user_rating_positive').click(function() {
  $('some_div').show();
}
Run Code Online (Sandbox Code Playgroud)

所以我想我的问题是在哪里/如何包含JavaScript?我不想填写该application.js文件,因为此JavaScript仅适用于此视图.我应该以某种方式为每个页面包含一个自定义JavaScript文件,还是将其粘贴在标题所查找的实例变量中?

bjg*_*bjg 152

我喜欢做的是在content_for :head块中包含每个视图的Javascript ,然后yield在应用程序布局中包含该块.例如

如果它很短,那么:

<% content_for :head do %>
  <script type="text/javascript">
    $(function() {
      $('user_rating_positve').click(function() {
        $('some_div').show();
      }
    });
  </script>
<% end %>
Run Code Online (Sandbox Code Playgroud)

或者,如果更长,那么:

<% content_for :head do %>
  <script type="text/javascript">
    <%= render :partial => "my_view_javascript"
  </script>
<% end %>
Run Code Online (Sandbox Code Playgroud)

然后,在您的布局文件中

<head>
  ...
  <%= yield :head %>
</head>
Run Code Online (Sandbox Code Playgroud)

  • 为什么不使用`<%= javascript_include_tag"my_javascipt_file"%>`? (39认同)
  • @AJP它比较麻烦,但它的http请求少于你的答案. (8认同)
  • @AJP我想那时它会破坏资产管道的目的 (5认同)
  • 我喜欢这篇文章http://railsapps.github.com/rails-javascript-include-external.html (4认同)
  • @lulalala,但答案中的代码不是那么做,但是以一种更混乱的方式? (2认同)

Ken*_*ant 103

如果你想在一个页面上包含javascript,你当然可以在页面上包含它,但是如果你想对你的javascript进行分组并利用资产管道,缩小的js等,它可以这样做并且有额外的通过将js拆分为仅适用于站点的某些控制器/视图/部分的组,将js资产组合并仅加载到特定页面上.

将资产中的js移动到文件夹中,每个文件夹都有一个单独的清单文件,因此,如果您有一个仅在后端使用的管理js库,则可以执行以下操作:

  • 资产
    • JavaScript的
      • 管理
        • JS ...
      • admin.js(管理员组的清单)
      • application.js(app全局组的清单)
      • 全球
        • JS ...

在现有的application.js中

//= require jquery
//= require jquery_ujs
//= require_tree ./global // requires all js files in global folder
Run Code Online (Sandbox Code Playgroud)

在新的admin.js清单文件中

//= require_tree ./admin // requires all js files in admin folder
Run Code Online (Sandbox Code Playgroud)

通过编辑config/production.rb确保加载了这个新的js清单

config.assets.precompile += %w( admin.js )
Run Code Online (Sandbox Code Playgroud)

然后调整页面布局,以便为页面头部添加一些额外的j:

<%= content_for :header %>   
Run Code Online (Sandbox Code Playgroud)

然后在想要包含此特定js组(以及普通应用程序组)和/或任何特定于页面的js,css等的视图中:

<% content_for :header do %>
  <%= javascript_include_tag 'admin' %>  
<% end %>
Run Code Online (Sandbox Code Playgroud)

您当然可以使用css执行相同的操作,并以类似的方式将其分组以仅应用于站点的某些区域.

  • 看起来你最终会得到许多脚本标签.我认为资产管道的目标是只有一个脚本标签?我只想编写javascripts,以便它们是特定于页面的. (2认同)

cai*_*nne 12

我更喜欢以下......

在您的application_helper.rb文件中

def include_javascript (file)
    s = " <script type=\"text/javascript\">" + render(:file => file) + "</script>"
    content_for(:head, raw(s))
end
Run Code Online (Sandbox Code Playgroud)

然后在您的特定视图中(此示例中为app/views/books/index.html.erb)

<% include_javascript 'books/index.js' %>
Run Code Online (Sandbox Code Playgroud)

......似乎对我有用.


Max*_*s S 12

这些答案对我帮助很大!如果有人想再多一点......

  1. 如果您希望将javascripts预编译,则需要将javascripts放入清单中.但是,如果您需要每个javascript文件,application.js.coffee那么每次导航到不同的页面时都会加载所有javacsripts,并且执行特定于页面的javascripts的目的将被取消.

因此,您需要创建自己的清单文件(例如speciifc.js),该文件将需要所有特定于页面的javascript文件.另外,修改require_treeapplication.js

应用程序/资产/ JavaScript的/ application.js中

//= require jquery
//= require jquery_ujs
//= require_tree ./global
Run Code Online (Sandbox Code Playgroud)

应用程序/资产/ JavaScript的/ specific.js

//= require_tree ./specific
Run Code Online (Sandbox Code Playgroud)

然后在environments/production.rb使用config选项将此清单添加到预编译列表中,

config.assets.precompile += %w( specific.js )

完成!应该始终加载的所有共享 javascripts将被放置在app/assets/javascripts/global文件夹中,并且页面特定的javascripts 将被放入app/assets/javascripts/specific.您只需从视图中调用特定于页面的javascripts即可

<%= javascript_include_tag "specific/whatever.js" %> //.js是可选的.

这已经足够了,但我也想利用它javascript_include_tag params[:controller].创建控制器时,会app/assets/javascripts像其他人提到的那样生成关联的coffeescript文件.有真正的控制器特定的 javascripts,只有在用户到达特定的控制器视图时才会加载.

所以我创建了另一个清单 controller-specific.js

应用程序/资产/ Javascript角/控制器specific.js

//= require_directory .

这将包括与控制器关联的所有自动生成的coffeescripts.此外,您需要将其添加到预编译列表中.

config.assets.precompile += %w( specific.js controller-specific.js )


AJP*_*AJP 9

如果你不想使用资产管道或复杂的工作来获得必要的页面特定的javascript(我同情),最简单和最健壮的方式,实现与上面的答案相同,但代码更少只是为了使用:

<%= javascript_include_tag "my_javascipt_file" %>
Run Code Online (Sandbox Code Playgroud)

注意:这确实需要每个include标记多一个http请求,而不是使用的答案 content_for :head


per*_*ine 7

看一下pluggable_js gem.您可能会发现此解决方案更易于使用.