Rails 3.1 JavaScript 资产管道
好吧,我已经阅读了很多关于 Rails 3.1 的新 Asset Pipeline 的信息,但我找不到正确的答案来解决我的疑问。
我根据我正在渲染的 view#action 按需加载 .js 文件。我这样做是为了防止错误的绑定并加载小 .js 文件。
candidate_opportunities#index
$(".sortable_drag_n_drop").sortable({
update: function(event, ui) {
$.post('/candidate_opportunities/sort', $(this).sortable('serialize'));
},
handle: 'span'
});
candidate_companies#index
$(".sortable_drag_n_drop").sortable({
update: function(event, ui) {
$.post('/candidate_companies/sort', $(this).sortable('serialize'));
},
handle: 'span'
});
$(".sortable_drag_n_drop").disableSelection();
现在最好的解决方案是什么?
- 我应该更改我的绑定并让 Sprockets 使用 <代码>//= require_tree . ?
- 或者我应该尝试加载我的 .js 根据我的观点,所以我最终不会得到一个巨大的 application.js?
Ok, I've read a lot of information about the new Asset Pipeline for Rails 3.1 and I couldn't find a proper answer to my doubt.
I was loading my .js files according to the view#action I was rendering, on demand. I was doing this to prevent incorrect bindings and to load small .js files.
candidate_opportunities#index
$(".sortable_drag_n_drop").sortable({
update: function(event, ui) {
$.post('/candidate_opportunities/sort', $(this).sortable('serialize'));
},
handle: 'span'
});
candidate_companies#index
$(".sortable_drag_n_drop").sortable({
update: function(event, ui) {
$.post('/candidate_companies/sort', $(this).sortable('serialize'));
},
handle: 'span'
});
$(".sortable_drag_n_drop").disableSelection();
What is the best solution now?
- Should I change my bindings and let Sprockets compile all my .js files using
//=
?
require_tree . - Or should I try to load my
.js according to my views, so I don't end up with a huge
application.js?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您要将其更新到管道,您有多种选择。在做出决定时,您可能应该考虑管道的工作方式。
从广义上讲,管道的目标是将所有 JS 加入到一个文件中,并对其进行 minfy/压缩。这样做的目的是减少每页的请求数量,并允许设置远期标头,以便将资源缓存在浏览器或透明代理/缓存中的某个位置。
关于选项。
1.就像你现在所做的那样。
你可以继续做你所知道的同样的事情。我假设您正在使用 Rails 助手在主布局文件中添加这些视图 JS 文件。您可以继续对管道执行相同的操作,但是您必须将使用的所有文件添加到预编译数组中:
config.assets.precompile += ['candidate_opportunities.js', 'candidate_companies']
资产必须位于 asset/javascripts 中,但无需将它们添加到清单文件中,因为您要单独添加每个资产。
强烈建议您坚持使用 Rails 默认管道并预编译生产资源。
缺点是这些页面上有额外的请求,但这只是当应用程序处于高负载时才会出现的问题。
2. Asset Pipeline Way (TM)
要使用管道执行此操作,您需要将这些文件移至 asset/javascripts 和
require_tree
中,如您所说。您的情况的问题是 JS 片段针对相同的类(但具有不同的帖子 URL),因此这是行不通的。使用 require_tree 时,文件的顺序可能不是您想要的。
新的 3.1 应用程序为视图生成文件(我认为),但期望它们将针对标记中的独特属性(从站点角度来看),因为所有文件都包含在 application.js 中
以解决以下问题JS 发生冲突。我建议您重构 JS 片段,使其更通用。您可以在可排序对象上使用
data-post-url
属性:然后在你的JS中收集url。
不仅是 DRYer,而且您的整体 JS 更少,并且可以按预期充分使用管道。
If you are updating this to the pipeline you have several options. You should probably take the way the pipeline should work into account in deciding.
Broadly speaking, the aim of he pipeline is to join all your JS into one file and minfy/compress it. The point in doing this is reduce the number of requests per page, and to allow far-future headers to be set so that the resource is cached at the browser or somewhere in a transparent proxy/cache.
On to the options.
1. The same as you do now.
You could keep doing the same thing as you do know. I presume that you are using the rails helpers to add these view JS files in the main layout file. You could keep doing the same with the pipeline, however you must add all the files you use to the precompile array:
config.assets.precompile += ['candidate_opportunities.js', 'candidate_companies']
The assets must be in assets/javascripts but there is no need to add them to the manifest file as you are adding each on individually.
It is highly recommended that you stick with the Rails defaults for the pipeline and precompile assets for production.
The downside is an extra request on those pages, but this is only an issue if the app is under high load.
2. The Asset Pipeline Way (TM)
To do this with the pipeline you would need to move these files into assets/javascripts and
require_tree
as you say.The issue in your case is that the JS snippets target the same class (but with a different post URLs), so this is not going to work. And with require_tree the order of the files might not be what you want.
A new 3.1 app generates files for views (I think), but the expectation is that they will target unique attributes (from a site perspective) in the markup, because all the files get included in the application.js
To get around the problem of JS clashes. I would suggest that you refactor the JS snippet so that it is more generic. You could use a
data-post-url
attribute on the sortable object:<ul class="sortable_drag_n_drop" data-post-url="/candidate_opportunities/sort">
and then collect the url in your JS.
Not only is that DRYer, but you have less overall JS and can fully use the pipeline as intended.
我对 Rails 资产管道感到沮丧。也许不是整个资产管道的事情,但 Rails 组织 javascript 的方式确实不合逻辑。
截至目前,Rails 每个控制器都有一个单独的 javascript 文件。这在逻辑组织方面有点好。但随后资产管道将所有这些文件压缩成一个大的 js 文件。所以基本上你的 js 文件组织得很好,但随后它们被一次性加载,导致变量冲突、函数冲突、其他代码冲突和其他意外行为。因为作为开发人员,我们真正想要的是一种执行或加载页面特定 JavaScript 的简单方法。
一种著名的方法是在每个页面中只包含一个特定的 javascript 文件。是的,这会起作用,但如果我们每个页面请求不同的 javascript 文件,我们就不会使用资产管道提供的性能提升。
我的解决方案是创建一个 javascript 对象,该对象包含所有特定于页面的函数,然后在 Rails 执行匹配的控制器-操作对后获取并执行它们。像这样的事情:
基本上,这就是核心思想。好吧,我已经实现了这个想法并为其创建了一个 gem。查看 Paloma,了解如何逻辑地组织 js 文件并执行特定于页面的 javascript,而无需复杂的设置。
以下是如何使用 Paloma 的示例:
Javascript 文件:
Rails 控制器:
这只是一个简单的示例,但它还有更多内容可以提供,我相信它可以解决您的问题。容易地。
谢谢你!
I'm frustrated on Rails asset pipeline. Maybe not the whole asset pipeline thing but the way Rails organize javascript is really not logical.
As of now, Rails has a separate javascript file per controller. Which is somewhat good in terms of logical organization. But then the asset pipeline compresses all those files into one big js file. So basically your js files are well organized but then they are loaded all at once, resulting to variable clashes, function clashes, other code clashes and other unexpected behavior. Because what we really want as developers is a simple way to execute or load a page specific javascript.
One famous approach is to just include a specific javascript file per page. Yes, that will work, but we are not using the performance boost given by the asset pipeline if we are requesting different javascript files per page.
My solution is to create an javascript object that holds all the page-specific functions then fetch and execute them once the matching controller-action pair is executed by Rails. Something like this:
Basically, that's the core idea. Well I've implemented that idea and created a gem for it. Checkout Paloma, and see how you can logically organize your js files and execute page-specific javascript without complex setups.
Here's an example on how Paloma is used:
Javascript file:
Rails controller:
That's just a quick example, but it has lot more to offer, and I'm sure it can solve your problem. Easily.
Thank You!