我想在我的资产管道中做这样的事情:
的application.js
//= require jquery
//= require jquery_ujs
//= require_tree ./includes
//= require global
<% if File.exists? "#{Rails.root}/assets/javascripts/#{params[:controller]}.js" %>
//= require <%= params[:controller] %>
<% end %>
<% if File.exists? "#{Rails.root}/assets/javascripts/#{params[:controller]}/#{params[:action]}.js" %>
//= require <%= params[:controller] %>/<%= params[:action] %>
<% end %>
现在这不起作用,因为资产文件无法访问params
变量。现在有没有办法从资产中获取当前控制器动作名称?
或者是整个项目预编译的资产文件,这是不可能的?
答案 0 :(得分:9)
你可以通过一些Tom Foolery来实现这一点,但我会高度反对它。
我这样说的原因是因为你希望这个js资源是可缓存的,并且在这种情况下它确实需要是静态的。根据正在调用的控制器来定制资产将导致潜在的大量独特资源,所有这些资源都应单独识别,下载和缓存。注意到你已经包含了明显不变的资源,比如jQuery,并思考这些需要一次又一次地下载的可能性,我认为这一点很明显,这种方法不能很好地工作。
如果你要做的是根据控制器/动作自定义视图的初始化,我建议在你提供的静态js资产中包含函数定义,然后可以直接从页面调用。
希望这有帮助。
答案 1 :(得分:5)
资产将被正常预编译,除非您禁用它并构建每个请求,否则这将无法实现。
如果这是为了加载一些只能在某些页面上的js,那么你仍然可以在你的视图中明确地包含该文件。
如果您出于性能原因而尝试这样做;每页加载1个js文件通常是最快的事情。整个文件可以缓存,每个页面加载它可以节省一些额外的请求。文件的大小几乎不是一个因素。
通常我会遵循将所有js文件塞进一个模式的模式,然后使用特征检测来启用某些javascript,例如,如果某个元素在页面上,则加载一些内容。
$("body#user_show").each(function() {
$(".user_info_box").each(load_user_info)
// ...
})
这样我可以缓存所有内容,只为我在页面上检测到的内容加载j。
答案 2 :(得分:2)
我不会在javascript本身中包含控制器名称,因为您希望缓存资产。更好的解决方案是使用标记中可能的数据属性来自定义脚本初始化过程。例如,
<body data-controller="<%= controller.controller_name %>" data-action="<%= controller.action_name %>">
然后在您的application.js中,您可以根据控制器名称调用模块,即。 Users.init()