繁体   English   中英

Rails 3.1 Asset Pipeline for Javascript

[英]Rails 3.1 Asset Pipeline for Javascript

好的,我已经阅读了很多有关新的Rails 3.1 Asset Pipeline的信息,但找不到我的疑问的正确答案。

我正在根据需要渲染的view#action加载.js文件。 我这样做是为了防止错误的绑定并加载小的.js文件。

候选人_机会#索引

$(".sortable_drag_n_drop").sortable({
    update: function(event, ui) {
        $.post('/candidate_opportunities/sort', $(this).sortable('serialize'));
    },
    handle: 'span'
});

候选人_公司#索引

$(".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文件//= require_tree .
  • 还是我应该根据自己的观点尝试加载.js ,因此我不会以庞大的application.js结尾?

如果要将其更新到管道中,则有几种选择。 在决定时,您可能应该考虑管道应起作用的方式。

广义上讲,管道的目的是将您所有的JS合并到一个文件中,并将其压缩/压缩。 这样做的目的是减少每页的请求数量,并允许设置远期头,以便将资源缓存在浏览器或透明代理/缓存中的某个位置。

转到选项。

1.与您现在相同。

您可以继续做自己知道的事情。 我假设您正在使用rails助手在主布局文件中添加这些视图JS文件。 您可以继续对管道进行操作, 但是必须将使用的所有文件添加到预编译数组中:

config.assets.precompile += ['candidate_opportunities.js', 'candidate_companies']

资产必须位于资产/ javascript中,但是无需分别将它们添加到清单文件中。

强烈建议您对管道使用Rails的默认值,并为生产预编译资产。

缺点是这些页面上的额外请求,但这仅是在应用程序负载高的情况下的问题。

2.资产管道方式(TM)

要通过管道执行此操作,您需要将这些文件移到资产/ javascript和您所说的require_tree中。

您遇到的问题是JS代码段针对相同的类(但具有不同的发布URL),因此这行不通。 使用require_tree,文件的顺序可能不是您想要的。

一个新的3.1应用程序会生成用于视图的文件(我认为),但是期望它们将以标记中的唯一属性(从网站角度)为目标,因为所有文件都包含在application.js中。

为了解决JS冲突的问题。 我建议您重构JS代码段,使其更通用。 您可以在可排序对象上使用data-post-url属性:

<ul class="sortable_drag_n_drop" data-post-url="/candidate_opportunities/sort">

然后在您的JS中收集网址。

不仅是DRYer,而且您的整体JS更少,并且可以按预期充分使用管道。

我对Rails资产管道感到沮丧。 也许不是整个资产流水线,但Rails组织javascript的方式确实不合逻辑。

到目前为止,Rails每个控制器都有一个单独的javascript文件。 就逻辑组织而言,这有点好。 但是随后资产管道将所有这些文件压缩为一个大js文件。 因此,基本上您的js文件组织得很好,但随后一次全部加载了它们,从而导致变量冲突,函数冲突,其他代码冲突和其他意外行为。 因为我们作为开发人员真正想要的是执行或加载页面特定javascript的简单方法。

一种著名的方法是每页仅包含一个特定的javascript文件。 是的,可以,但是如果我们要求每页使用不同的javascript文件,那么我们不会使用资产管道所提供的性能提升。

我的解决方案是创建一个JavaScript对象,该对象包含所有特定于页面的函数,然后在Rails执行了匹配的控制器-动作对后,提取并执行它们。 像这样:

PageJs = {};
PageJs["users/new"] = function(){ 
  alert("I will be called when users/new action is executed");
};

基本上,这就是核心思想。 好吧,我已经实现了这个想法,并为此创建了一个瑰宝。 检出Paloma ,了解如何在不进行复杂设置的情况下逻辑上组织js文件并执行特定于页面的javascript。

这是有关如何使用Paloma的示例:

Javascript文件:

Paloma.callbacks['users/new'] = function(params){
  // This will only run after executing users/new action
  alert('Hello New Sexy User');
};

Rails控制器:

def UsersController < ApplicationController
  def new
    @user = User.new
    # No special function to call, 
    # the javascript callback will be executed automatically
  end
end

那只是一个简单的例子,但是它提供了更多的东西,我相信它可以解决您的问题。 容易。

谢谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM