如果 javascript 仅用于特定页面,为什么不应该放在视图中?

Why shouldn't javascript be placed in view if it is only used on specific pages?

his answer Richard Peck 中写道:

不显眼的 JS

还有一点需要考虑(您已经这样做了),那就是您确实需要在您的应用程序中使用不显眼的 javascript。

Unobtrusive JS 基本上意味着您能够将页面中的“绑定”抽象为资产管道中的 Javascript 文件。这有几个重要的原因:

  • Your JS can be loaded on any page you want (it's DRY)

  • Your JS will reside in the "backend" of your app (won't pollute views)

  • You'll be able to use the JS to populate the various elements / objects you want on screen

总是建议您将 JS 放入单独的文件中 - 包括在视图中会让您陷入混乱

我要回答以下问题:

If I am only using a script on a certain page, why would I want to have it load on every page? Doesn't that go against the DRY? Maybe I am not properly understanding how the Rails pipeline works.

如果是 Turbolinks 应用程序,脚本不会加载到每个页面上。在 Turbolinks 中,你的 javascript 被加载一次,并且在你的应用程序的整个生命周期中都存在。因此,您可以将该页面特定的脚本放在主 application.js 文件中,并且当页面首次加载时,您的整个 js 代码(application.js 中的所有内容)基本上只加载一次。如果您使用 Rails 但不使用 Turbolinks 或其他 ajax 技术(如客户端 javascript 框架),则将针对每个请求评估特定页面 javascript,因此有点像你说的那样违反 DRY 并损害性能。

If I am only using a script on a certain page, why would I want to have ityo load on every page?

总而言之,Turbolinks 在这方面与 Angular\Backbone\Any 大多数其他 javascript 框架非常相似:您基本上只需在 html 布局,无论 html 用户导航到您应用程序中的 javascript 代码,都不会被评估超过一次。

Rails pipeline

这不是Rails管道,unobtrusive JS是标准编程模式。

从页面 ("inline") 中提取 JS 到外部文件清理页面,仅此而已。

如果你想快速加载页面,你需要将JS拆分成单独的文件。这可以采用 类 的形式,但主要用于特定于页面的功能。例如,您可能有 admin.jsapplication.js.


Rails

关于 Rails 具体来说,处理不引人注目的 JS 的方式归结为你如何 precompile 你的资产。标准的方法是将 所有 功能放入 application.js - 这显然会变得臃肿。

解决这个问题的方法是使用 config.assets.precompile 挂钩 - 允许您指定要包含的文件作为单独的预编译元素:

# config/application.rb
config.assets.precompile << %w(admin.js cart.js etc.js)

这将更改为 handled by manifest.js in Sprockets 4+ (I can explain this in an update if required). I made a commit 他们的回购协议。

这意味着当您预编译资产时(或者当您在开发中 运行 它们时——它们被缓存),您将获得 admin.js 或您定义为单独预编译的任何内容。这本身没有任何意义;这些文件只会出现在 public/assets.

的意思是您可以在 布局:

中引用文件
# app/views/layouts/application.html.erb
<%= javascript_include_tag :application, (:admin if [[condition]]) %>

or

# app/views/layouts/admin.html.erb
<%= javascript_include_tag :admin %>

因此,您将能够在需要时调用所需的文件。

我可以进行更深入的探讨,但这应该可以回答眼前的问题。