5

好的,我已经阅读了很多关于 Rails 3.1 的新资产管道的信息,但我找不到正确的答案来解决我的疑问。

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

候选人机会#index

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

候选人公司#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 使用 .js 编译我的所有 .js 文件//= require_tree .吗?
  • 或者我应该尝试 根据我的观点 加载我的.js ,这样我就不会得到一个巨大的application.js
4

2 回答 2

6

如果您将其更新到管道,您有几个选项。您可能应该在决定时考虑管道的工作方式。

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

关于选项。

1.和你现在一样。

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

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

资产必须在 assets/javascripts 中,但无需将它们添加到清单文件中,因为您正在单独添加它们。

强烈建议您坚持使用 Rails 的管道默认设置,并为生产环境预编译资产。

缺点是这些页面上的额外请求,但这仅在应用程序处于高负载下时才会出现问题。

2. Asset Pipeline Way (TM)

要使用管道执行此操作,您需要将这些文件移动到 assets/javascripts 中,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 中收集 url。

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

于 2011-09-18T21:29:18.777 回答
0

我对 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");
};

基本上,这是核心思想。好吧,我已经实现了这个想法并为它创建了一个 gem。查看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');
};

导轨控制器:

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

这只是一个简单的示例,但它提供了更多功能,我相信它可以解决您的问题。容易地。

谢谢你!

于 2012-12-22T02:38:52.570 回答