如何使用Rails资产管道进行每页javascript

我理解,出于性能原因,最好让资产管道连接并缩小我的所有javascript,并将每个页面请求发送到整个批次。 这很公平

但是,我的一堆javascript就像将特定行为绑定到特定页面元素之类的东西 – 比如

$('button').click(function(e) { $('input.sel').val(this.name); } 

如果我知道这个代码只在那个页面上执行,我会感觉更舒服 – 而不是在其他页面上可能巧合地使用相同ID或匹配相同选择器的元素人们如何处理这个?

我宁愿不把所有这些东西都放在元素内联中,只是因为当它变得超过两行长时,保持javascript正确缩进到.html.erb文件中是比它需要更多的工作

这是我做的(基于一些stackoverflow答案):

application_helper.rb

 def body_page_name [controller_name.classify.pluralize, action_name.classify].join end 

application.html.haml

  %body{data: {page: body_page_name}} 

的application.js

 $(function() { var page = $("body").data("page"); if("object" === typeof window[page]) window[page].init(); }); 

在适当的js文件中有一个名为ControllerAction的对象:

tickets.js

 var TicketsShow = new function() { var self = this; self.init = function() { // code which may call other functions in self }; }; 

可能有更好的方法,但这对我有用

我将描述我目前正在做的事情,以防它给了任何人一个更好的主意

1)我更改了application.html.erb中的’body’标签,将当前控制器和操作添加为数据属性

  

2)我在相关的javascript顶部测试这个

 $(document).ready(function() { if($('body').data('controller')=='stories') { $('.story').click(function(e) { var u=$(this).data('url'); u && (document.location=u); }); } }); 

我无法决定我是否认为这是一个好主意

对于特定于页面的JavaScript,我通常会执行以下操作:

应用助手

在应用程序助手中,我创建了一个类属性(尽管你也可以使用数据属性)。

 module ApplicationHelper def body_attributes controller = params[:controller].gsub('/', ' ') action = params[:action] version = @version ? "version_#{@version}" : nil { class: ([controller, action, version] - [nil]).join(' ') } end end 

注意我还添加了一个版本字符串。 这有助于Google内容实验,并使A / B测试变得轻而易举。

Application.html.haml

在我的全局布局文件中,我这样做是为了在body标签上插入属性:

 !!! 5 %html %head ... %body{body_attributes} 

的script.js

现在在我的页面特定脚本中,我只检查类属性,如下所示:

 $(function () { if ($('body.pledge.new, body.pledge.create').length > 0) { // do work here... } }); 

这种方法的优点是按类别获取身体非常快。 条件中的脚本根本不会在我选择的页面之外的任何页面上执行,因此开销最小,而且我不需要在整个代码中更改我的选择器。

编辑

请注意,这个答案现在已经有3年了。 您应该使用像React这样的框架来使用客户端路由。

我将一个类添加到BODY标记中,允许您识别每个页面,从而确定每页的每个控件。

  

JS:

 $('.page1 button').click(function(e) { $('input.sel').val(this.name); } 

我已经完成了它,看到它以几种不同的方式完成:

  1. assemblymvc以便能够每页加载一个特定的js文件,与控制器文件一样命名。 喜欢: .js

  2. 在JS中创建一个url解析器,然后将一个全局变量设置为当前页面: UrlParams.currentView = 'dashboard'; 然后说if(UrlParams.currentView == 'dashboard') { //do specific js here }

  3. 将唯一标识符设置为页面类或ID,然后使用JS选择器进行定位。 $('#dashboard').xyz();