如果我在Rails 3.1中生成一个新控制器,也会自动添加一个带有控制器名称的javascript文件。首先,我认为这个javascript文件只会在调用相关控制器时使用。
默认情况下,//= require_tree .
文件中有指令application.js
,其中包含树上的每个javascript文件。
如何只加载特定于控制器的脚本?
答案 0 :(得分:122)
仅加载必要的name_of_the_js_file.js文件:
从//=require_tree
application.js
在资产管道中保留您的js文件(在加载特定页面时要加载)
在application_helper.rb
def javascript(*files)
content_for(:head) { javascript_include_tag(*files) }
end
进入你的布局:
<%= yield(:head) %>
在您的视图文件中添加:
<% javascript 'name_of_the_js_file' %>
然后应该没问题
答案 1 :(得分:83)
优雅的解决方案是在javascript_include_tag
中要求controller_name请参阅http://apidock.com/rails/ActionController/Metal/controller_name/class
<%= javascript_include_tag "application", controller_name %>
controller_name.js将被加载并且也在资产中,因此您可以从此处获取其他文件。
示例,渲染汽车#index将给出
<%= javascript_include_tag "application", "cars" %>
其中cars.js可以包含
//= require wheel
//= require tyre
享受!
答案 2 :(得分:28)
我总是在布局文件中包含这个。它可以将你的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") %>
答案 3 :(得分:6)
您的问题可以通过不同方式解决。
请注意,这不是生产模式的良好解决方案,因为您的控制器细节不会被预编译!
向我们的应用程序助手添加以下方法:
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
调用layout
- 文件中的帮助方法:
<%= include_related_asset(params[:controller].to_param + '_' + params[:action].to_param . 'js') %>
为您的控制器操作创建特定资产。 E. g。 controller_action.js
请不要忘记将YourApp
更改为您的应用名称。
yield
<%= yield :head%>
添加到布局头从您的操作视图中包含您的资源:
<% content_for :head do %>
<%= javascript_include_tag 'controller_action' %>
<% end %>
有关详细信息,请参阅Rails guides。
答案 4 :(得分:3)
我喜欢albandiguer's solution。我发现javascript / coffeescript资产没有单独预编译。这会导致尝试使用javascript_path
的各种错误。在我解决他的评论中提到的一些问题后,我将分享我对该问题的解决方案。主要处理名为JavaScript文件的部分控制器。
所以我构建了一个应用程序帮助器来检测javascript目录中是否存在该文件,而不管.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文件的完整路径(如果存在)。否则返回nil。因此,遵循Pencilcheck的评论,您可以为条件包括添加此方法:
<%= javascript_include_tag(controller_name) if javascript_asset_path(controller_name) %>
现在你有一个适当的条件包括。现在讨论预编译资产。通常用于单独优化 you don't want assets precompiled 。但是,如果你必须这样做,你可以这样做:
# Live Compilation
config.assets.compile = true
您可以添加此环境配置文件。首先在开发环境文件中测试它。再次这是不合理的。 Rails资产管道使用Sprockets来优化所有内容:
Sprockets加载指定的文件,必要时处理它们, 将它们连接成一个文件,然后压缩它们(如果 Rails.application.config.assets.compress为true)。通过提供一个文件 而不是很多,页面的加载时间可以大大减少 因为浏览器提出的请求较少。压缩也减少了 文件大小,使浏览器能够更快地下载它们。
请阅读文档,了解Sprockets (Asset Pipeline) 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's example:
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文件列表,其中没有目录路径。请注意,如果您的控制器名称是复数,则javascript名称也应该是。另请注意,如果控制器是单数且javascript文件是复数,则仍会包含它,因为the_file[a_controller]
将成功进行部分匹配。
您可以在Rails.application.config.assets.precompile
设置中试用此功能。我知道这可以正确地获取文件列表。但是我会让你去测试它。让我知道,由于我很好奇,预编译是否有任何细微差别。
有关资产预编译如何查看此博客的详尽说明:http://www.sitepoint.com/asset-precompile-works-part/
答案 5 :(得分:1)
我最近发现了一种为特定控制器使用生成脚本的简单方法。我用于该解决方案gem gon。添加控制器:
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...
就是这样。