【问题标题】:Efficient way to manage javascript/coffeescript code for Rails 5?管理 Rails 5 的 javascript/coffeescript 代码的有效方法?
【发布时间】:2018-01-15 02:33:42
【问题描述】:

我正在 Rails 5.0.2 中构建一个 Web 应用程序。我的项目有以下 JS 文件:

此外,我自己的每个 JS 文件都有类似的模式,如下所示:

$(function () {
    var init = function () {
        // my code, I want to run on specific page load i.e. /remarks
        $('form#cf_remarks_form').validate(validate_options);
    };
    init();
    document.addEventListener("turbolinks:load", function () {
        init();
    });
});

我对使用 JS 资产有以下保留/疑问:

  1. Rails 默认附加(并因此运行)所有页面上的所有 js 文件以实现相同的布局。通过使用自定义模式或使用默认模式只在特定资源/页面上添加相关的js是否很好?

  2. 如果所有 js 组合并链接到每个页面,我需要非常具体/谨慎,同时使用 jQuery 选择器作为一个页面的选择 $('div.custom input.no-search') 可能会让我发疯如果我不想在另一个页面上运行方法有很多代码和限定标记,则提到的选择器正在选择。

  3. Rails 5 对普通页面使用 ajax 加载。如果页面 /company 有文件 company.js,它将在第一页执行,例如 /home。当我转到 /company 时,company.js 中编写的行将不会再次执行。因此,我必须使用 turbolinks:load 事件侦听器并将每个 UI 初始化和 UI 附加事件封装在一个方法中,以便在 turbolinks:load 以及正常调用中调用。 (如代码sn-p所示)

所以,我想知道 Rails 开发人员对 js 资产特别是使用 Rails 5 的人遵循什么做法?如果您的回答能解决我上面提到的问题,那将是非常有帮助的。

【问题讨论】:

    标签: javascript jquery ruby-on-rails ruby-on-rails-5 asset-pipeline


    【解决方案1】:

    回答您的问题:

    1. 视情况而定。我建议首先尝试使用默认值 - 它只要求您遵守选择器和类名。但是,如果您发现自己在每个页面上都包含大量仅用于一个后端页面的 js,请参阅下面的其他可能性。
    2. 是的,只需使用特定于您所针对的资源的类名,例如 .remarks_form,如果在页面上找不到该类名,每个函数中的 js 可以提前退出(所以您知道页面不是相关的)。
    3. 您应该编写您的 js,使其仅在页面加载后触发,这样每次页面加载都会触发一次 - 无需两次 init() 调用,只需在文档加载时触发,或者在 turbolinks 情况下涡轮链接:加载。即使不使用 turbolinks 或 rails,这实际上也是一种很好的做法,因为您希望在 js 开始触发之前加载和初始化页面。

    您应该可以将它与 rails 5 一起使用:

    document.addEventListener("turbolinks:load", function() {
        console.log('Loads each time');
    });
    

    查看文档:

    http://guides.rubyonrails.org/working_with_javascript_in_rails.html#turbolinks

    这里有一个权衡。您可以内联或在许多单独的文件中包含特定于页面的 js,但随后浏览器必须对其发出另一个请求,并且可能不会将其缓存。 Rails 选择让事情保持简单,并假设为每个页面缓存一个文件优于整个站点的 50 个不同的 js 文件。 YMMV 但这似乎运作良好,所以我会先尝试 Rails 方式。

    如果您觉得不方便,您可以通过各种方式解决 Rails 设置问题。我建议将您的大部分 js 放在一个组中,但您也可以(按复杂程度排序):

    1. 将大部分 js 保留在主文件中,但将一些 js 内嵌在仅与该页面相关的页面上
    2. 在页面标题中导入特定于页面的静态 js 文件(例如,仅在后端屏幕上用于文本编辑器组件的 js)。
    3. 将您的 js 拆分为资产组并仅在某些页面上导入一些组 - 请参阅details 的此答案。

    【讨论】:

    • 我有一点担心“不需要两次 init() 调用”。我已经测试过,如果您刷新页面或通过直接 URL 打开它,任何包含在 turbolinks:load 中的东西都不会执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2011-03-29
    • 2012-11-14
    • 2014-03-08
    • 2019-03-03
    • 2014-10-16
    • 1970-01-01
    相关资源
    最近更新 更多