Rails 3.1资产pipe道:如何加载控制器特定的脚本?

如果我在Rails 3.1中生成一个新的控制器,也会自动添加一个带有控制器名称的JavaScript文件。 首先,我认为这个JavaScript文件将被使用,当相关的控制器被调用。

默认情况下有指令//= require_tree .application.js文件中,包括树上的每个JavaScript文件。

我怎么能只加载控制器特定的脚本?

只加载必要的name_of_the_js_file.js文件:

  1. application.js移除//=require_tree

  2. 在资产pipe道中保留你的js文件(你想要在加载特定页面的时候加载)

  3. application_helper.rb添加一个帮助application_helper.rb

     def javascript(*files) content_for(:head) { javascript_include_tag(*files) } end 
  4. 屈服于你的布局:

     <%= yield(:head) %> 
  5. 在你的视图文件中添加这个:

     <% javascript 'name_of_the_js_file' %> 

那应该没问题

一个优雅的解决scheme是要求您的javascript_include_tag中的controller_name

请参阅http://apidock.com/rails/ActionController/Metal/controller_name/class

 <%= javascript_include_tag "application", controller_name %> 

controller_name.js将被加载并且也在资产中,因此您可以从这里请求其他文件。

例如,渲染汽车#索引会给

 <%= javascript_include_tag "application", "cars" %> 

cars.js可以包含的地方

 //= require wheel //= require tyre 

请享用 !

我总是将这个包含在我的布局文件中。 它可以把你的js的范围作为行动

 <%= javascript_include_tag params[:controller] if AppName::Application.assets.find_asset("#{params[:controller]}.js") %> <%= javascript_include_tag "#{params[:controller]}_#{params[:action]}" if AppName::Application.assets.find_asset("#{params[:controller]}_#{params[:action]}.js") %> 

你的问题可以用不同的方式解决。

dynamic添加资产

请考虑这不是一个好的解决scheme的生产模式,因为您的控制器细节将不会被预编译!

  1. 添加到我们的应用程序帮手下面的方法:

     module ApplicationHelper def include_related_asset(asset) # v-----{Change this} if !YourApp::Application.assets.find_asset(asset).nil? case asset.split('.')[-1] when 'js' javascript_include_tag asset when 'css' stylesheet_link_tag asset end end end end 
  2. 调用layout文件中的帮助器方法:

     <%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %> 
  3. 为您的控制器操作创build特定的资产。 例如, controller_action.js

请不要忘记将YourApp更改为您的应用程序的名称。

使用yield

  1. <%= yield :head%>到布局头部
  2. 包含您的操作视图中的资源:

     <% content_for :head do %> <%= javascript_include_tag 'controller_action' %> <% end %> 

请参阅Rails指南了解更多信息。

另一个select是使用pluggable_js gem。

我喜欢albandiguer的解决scheme 。 我发现javascript / coffeescript资源没有单独预编译。 这导致各种尝试使用javascript_path的错误。 我在解决他的评论中提到的几个人的问题后,将分享我的解决scheme。 主要只处理一部分名为JavaScript文件的控制器。

所以我build立了一个应用程序助手来检测文件是否存在于javascript目录中,而不pipe.coffee / .js扩展名:

 module ApplicationHelper def javascript_asset_path(basename) Sprockets::Rails::Helper.assets.paths.select{|i| i =~ /javascript/ and i =~ /#{Rails.root}/ }.each do |directory| if Dir.entries(directory).map {|i| i.split('.')[0]}.compact. include? basename return File.join(directory, basename) end end nil end end 

如果存在,该方法将返回javascript文件的完整path。 否则返回nil。 所以下面的Pencilcheck的评论你可以添加这个方法的条件包括:

 <%= javascript_include_tag(controller_name) if javascript_asset_path(controller_name) %> 

现在你有一个适当的条件包括。 现在是预编译资产的问题。 通常为了优化, 你不需要单独预先编译资源 。 但是,如果您必须:

 # Live Compilation config.assets.compile = true 

你可以添加这个你的环境configuration文件。 先在您的开发环境文件中进行testing。 这又是不明智的。 Rails资产pipe道使用Sprockets来优化一切:

链轮加载指定的文件,如果必要的话处理它们,将它们连接成一个文件,然后压缩它们(如果Rails.application.config.assets.compress为true)。 通过提供一个文件而不是多个文件,页面的加载时间可以大大减less,因为浏览器请求较less。 压缩还可以减小文件大小,使浏览器能够更快地下载文件。

请阅读文件链轮机制(资产pipe道)的进一步细节http://guides.rubyonrails.org/asset_pipeline.html

资产不是单独预编译的。 例如,当我尝试:

 <%= javascript_include_tag 'event' %> 

我得到:

Sprockets :: Rails :: Helper :: AssetFilteredError:资产被过滤掉,不会被服务:添加Rails.application.config.assets.precompile += %w( event.js )config/initializers/assets.rb并重新启动服务器

所以你可以包含哪些资源被单独预编译。 我们只需要在我们的资产初始化器中添加名为javascript文件的相关控制器。 那么我们可以通过编程来做到这一点。

要获得控制器名称的列表,我将使用ecoologic的例子 :

 all_controllers = Dir[ Rails.root.join('app/controllers/*_controller.rb') ].map { |path| path.match(/(\w+)_controller.rb/); $1 }.compact 

现在要获取与控制器名称的基本名称匹配的所有javascript文件的名称,可以使用以下命令:

 javascripts_of_controllers = Sprockets::Rails::Helper.assets.paths.select{|a_path| a_path =~ /javascript/ and a_path =~ /#{Rails.root}/ }.map {|a_path| Dir.entries(a_path) }.flatten.delete_if {|the_file| !the_file['.js'] }.collect {|the_file| the_file if all_controllers.any? {|a_controller| the_file[a_controller]} } 

那么你可以尝试:

 # config/initializers/assets.rb Rails.application.config.assets.precompile += javascripts_of_controllers 

这将得到一个列表,所有的JavaScript文件,没有目录path,匹配您的控制器名称。 请注意,如果您的控制器名称是复数,则JavaScript名称也应该是这样。 另外请注意,如果控制器是单数的,并且JavaScript文件是复数,这将仍然包括它,因为the_file[a_controller]将成功部分匹配。

随意试试你的Rails.application.config.assets.precompile设置。 我知道这正确地得到你的文件列表。 但是我会离开你去testing它。 让我知道是否有任何与预编译有关的细微差别,因为我很好奇。

有关资产预编译的详细说明,请参阅此博客: http : //www.sitepoint.com/asset-precompile-works-part/

我最近发现了一个简单的方法来使用特定控制器生成的脚本。 我用这个解决schemegem 。 添加一个控制器:

 class HomesController < ApplicationController before_filter :remember_controller private def remember_controller gon.controller = params[:controller] end end 

之后,打开你的homes.js.cofee并添加在文件的开头:

 jQuery -> if gon.controller == "sermons" # Place all functions here... 

就这些。