javascript - 使用Rails 3.1,将页面" 特定" 的Javascript代码放在哪里?

  显示原文与译文双语对照的内容

在我看来,所有的javascript都合并到 1文件中。 Rails 在将 //= require_tree. 添加到 application.js Manifest 文件的底部时,默认情况下这样做。

这听起来像一个真正的life-saver,但我对 page-specific javascript代码有点担心。 这里代码是否在每一页上执行? 最后我希望我所有的对象被实例化时每一页只需要 1页面上。

同样,代码冲突也不存在?

或者你是否在页面的底部放置了一个小的script 标记,它只调用一个执行页面javascript代码的方法?

你不再需要 require.js 了?

谢谢

编辑: 我欣赏所有的答案。。 我认为他们并没有真正解决这个问题。 其中一些是关于样式的,但似乎没有关联。。 还有其他人提到 javascript_include_tag 。。 我知道存在( 显然。。),但是 Rails 3.1的方法是将所有的Javascript打包为 1个文件,而不是在每个页面底部加载单个 Javascript 。

我能想出的最好的解决方案是将某些特性与 id 年代或 class es div 标签。 在javascript代码中,你只需检查 id 或者 class 是否在页面上,如果是,则运行与它相关的javascript代码。 如果动态元素不在页面上,javascript代码不会运行- 即使它包含在由链轮打包的大量 application.js 文件中。

我的上述解决方案有好处,如果搜索框包含在 8页的100页上,它将只在 8页上运行。 你也不必在站点的8页上包含相同的代码。 事实上,你永远都不需要在你的站点上包含手动脚本标记。

我认为这是我的问题的实际答案。

时间:

资产管道文档建议如何执行 controller-specific:

例如如果一个在 app/assets/stylesheets/projects.css.scss. ProjectsController app/assets/javascripts/projects.js.coffee 处生成的,会有一个新的文件,另一个是你应该将任何js或者CSS控制器内各自的独特性资源加载文件,因为这些文件又可以仅仅为了这些控制器与线条如 <%= javascript_include_tag params [:controller] %> 或者 <%= stylesheet_link_tag params [:controller] %> 。

http://guides.rubyonrails.org/asset_pipeline.html

对于 page-specific js,你可以使用 Garber-Irish解决方案

所以你 Rails javascripts文件夹可能看起来像这两个控制器——汽车和用户:


javascripts/
├── application.js
├── init.js
├── markup_based_js_execution
├── cars
│ ├── init. js
│ ├── index.js
│ └──.. .
└── users
 └──.. .

而javascript看起来像这样:


//application.js

//= 
//= require init.js
//= require_tree cars
//= require_tree users



//init.js

SITENAME = new Object();
SITENAME.cars = new Object;
SITENAME.users = new Object;

SITENAME.common.init = function (){
//Your js code for all pages here
}



//cars/init.js

SITENAME.cars.init = function (){
//Your js code for the cars controller here
}



//cars/index.js

SITENAME.cars.index = function (){
//Your js code for the index method of the cars controller
}

markup_based_js_execution将包含用于UTIL对象和 DOM-ready UTIL.init 执行的代码。

别忘了把它放到你的布局 file:


<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">

我也认为使用类代替 data-* 属性更好,更好的page-specific css 。 就像 Jason Garber所提到的: page-specific CSS选择器会变得非常笨拙( 当你使用 data-* 属性时)

我希望这对你有帮助。

你已经回答了你自己的问题,但下面是另一个选项:

基本上,你是在假设

 
//= require_tree. 

 

是必需的。它不是。请随意删除它。 以我目前的应用程序,第一个我做 3.1. x 坦白地说,我做了三个不同的顶级js文件。 我的application.js 文件只有


//= require jquery
//= require jquery_ujs
//= require_directory. 
//= require_directory./api
//= require_directory./admin

通过这种方式,我可以用它们自己的顶级JS文件创建子目录,这些文件只包括我需要的。

关键是:

  1. 你可以删除 require_tree - Rails 让你更改它所做的假设
  2. application.js 这个名字没有什么特别之处——资产/javascript子目录中的任何文件可以包括与//= pre-processor指令

希望能帮助并添加一些细节来回答 closurecowboy 。

Sujal

另一个选项:创建page-或者model-specific文件,你可以在 assets/javascripts/ 文件夹中创建目录。


assets/javascripts/global/
assets/javascripts/cupcakes
assets/javascripts/something_else_specific

你的主 application.js 清单文件可以配置为从 global/ 加载它的文件。 特定的页面或者页面组可以有自己的清单,这些清单从自己的特定目录加载文件。 链轮会自动将 application.js 加载的文件与你的page-specific文件组合在一起,从而使这个解决方案能够工作。

这里技术也可以用于 style_sheets/

我欣赏所有的答案。。 我认为他们并没有真正解决这个问题。 其中一些是关于样式的,但似乎没有关联。。 还有其他人提到 javascript_include_tag 。。 我知道存在( 显然。。),但是 Rails 3.1的方法是将所有的Javascript打包为 1个文件,而不是在每个页面底部加载单个 Javascript 。

我能想出的最好的解决方案是将某些特性与 id 年代或 class es div 标签。 在javascript代码中。然后你只检查 id 或者 class 是否在页面上,如果是,则运行与它相关的javascript代码。 如果动态元素不在页面上,javascript代码不会运行- 即使它包含在由链轮打包的大量 application.js 文件中。

我的上述解决方案有好处,如果搜索框包含在 8页的100页上,它将只在 8页上运行。 你也不必在站点的8页上包含相同的代码。 事实上,你永远都不需要在你的站点上包含手动脚本标记- 除了可能会加载数据。

我认为这是我的问题的实际答案。

我意识到我要加入这个聚会有点晚了,但是我想在最近使用的解决方案中加入。 但是,让我先提一下。。

的Rails 3.1/3.2 方式(不,先生。 我不喜欢。)

查看:http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline

为了满足这个问题的完整性,我包括以下内容,因为它不是一个unviable解决方案。 虽然我对它不太在意。

"Rails 方式"是一个controller-oriented解决方案,而不是作为这个问题的原始作者的view-oriented 。 有 controller-specific JS文件以各自的控制器命名。 所有这些文件都放在一个文件夹树中,默认情况下在任何 application.js 要求指令中都不包含这些文件。

要包含controller-specific代码,在视图中添加以下内容。


<%= javascript_include_tag params[:controller] %>

我讨厌这个解决方案,但它已经存在,而且很快。 假设你可以将这些文件称为"people-index 。js"和"people-show 。js",然后使用 "#{params[:controller]}-index" 来获得view-oriented解决方案。 同样,快速修复,但它并不适合我。

将我的数据属性方式

我疯狂地说,但是我想在部署时把所有的JS编译并缩小到 application.js 。 我不想忘了把这些小的straggler文件放在各处。

我将所有的JS加载到一个紧凑的soon-to-be浏览器缓存,文件。 如果我的application.js的某个部分需要在页面上激发,我就会让HTML告诉我,而不是 Rails 。

我使用了一个名为 data-jstags的自定义数据属性,而不是将我的JS锁定到特定元素标识或者带标记类的HTML 。


<input name="search" data-jstag="auto-suggest hint"/>

在每个页面中,我使用-插入首选js库方法dom已完成加载时运行代码。 这里引导代码执行以下操作:

  1. 在标记为 data-jstag的DOM中迭代所有元素
  2. 对于每个元素,在空间上拆分属性值,创建一个标记字符串数组。
  3. 对于每个标记字符串,在该标记的哈希中执行查找。
  4. 如果找到匹配的键,运行与之关联的函数,将元素作为参数传递。

假设我的application.js 中有如下定义:


function my_autosuggest_init(element) {
/* Add events to watch input and make suggestions... */
}

function my_hint_init(element) {
/* Add events to show a hint on change/blur when blank... */
/* Yes, I know HTML 5 can do this natively with attributes. */
}

var JSTags = {
 'auto-suggest': my_autosuggest_init,
 'hint': my_hint_init
};

自举事件将对搜索输入应用 my_autosuggest_initmy_hint_init 函数,将它的转换为输入,以便在用户输入建议列表时显示建议列表,当输入为空且没有焦点时提供某种输入提示。

除非使用 data-jstag="auto-suggest" 标记了某个元素,否则auto-suggest代码不会激发。 但是,它总是在那里,缩小并最终缓存在我的application.js 中,我需要它在页面上。

如果你需要将额外的参数传递给标记的JS函数,你必须应用一些创造性。 添加data-paramter属性,提出一些参数语法,甚至使用混合方法。

即使我有一些看起来像controller-specific的复杂工作流,我还是会在lib文件夹中创建一个文件,将它打包到 application.js, 中,并用类似'new-thing-wizard'的东西标记它。 当我的Bootstrap 点击那个标记时,我漂亮漂亮的向导将会被实例化并运行。 它在需要时为控制器运行,但没有在控制器上附加。 事实上,如果我对向导进行了编码,我可能能够在视图中提供所有配置数据,因此以后可以为任何需要它的其他控制器提供 re-use 。

无论如何,这就是我现在实现页面特定的JS的方式,它为简单的站点设计和更复杂的/丰富的应用程序提供了良好的服务。 希望我在这里展示的两个解决方案中的一个,我的方式或者 Rails 方式,对将来遇到这个问题的任何人都有帮助。

这已经得到了很久的答复和接受,但是我提出了自己的解决方案,基于一些答案和我对 Rails 3 +的经验。

资产管道是甜蜜的。 使用它。

首先,在 application.js 文件中删除 //= require_tree.

然后在 application_controller.rb 中创建 helper 方法:


helper_method :javascript_include_view_js//Or something similar

def javascript_include_view_js
 if FileTest.exists?"app/assets/javascripts/"+params[:controller]+"/"+params[:action]+".js.erb"
 return '<script src="/assets/'+params[:controller]+'/'+params[:action]+'.js.erb" type="text/javascript"></script>'
 end
end

然后在 application.html.erb 布局文件中,在现有的javascript中添加新的helper,包括 raw helper:


<head>
 <title>Your Application</title>
 <%= stylesheet_link_tag"application", :media =>"all" %>
 <%= javascript_include_tag"application" %>
 <%= raw javascript_include_view_js %>
</head>

瞧,现在你可以很容易地创建view-specificjavascript使用相同的文件结构在 Rails 使用在其他地方。 只需将你的文件粘贴在 app/assets/:namespace/:controller/action.js.erb

希望能帮助其他人 !

你可以在布局文件中添加此行( 例如。 application.html. ) 自动加载控制器特定的javascript文件:


<%= javascript_include_tag params[:controller] %>

你还可以添加一行以在per-action基础中自动加载脚本文件。


<%= javascript_include_tag params[:controller] +"/" + params[:action] %>

只需将你的页面脚本放入一个名为控制器名的subdirectoriy 。 在这些文件中,你可以使用=require包含其他脚本。 最好创建一个 helper 来包含文件,只有在它存在时,才能避免在浏览器中出现 404失败。


<%= javascript_include_tag params[:controller] %>

也许你会发现 pluggable_js gem宝石是合适的解决方案。

...