Why shouldn't javascript be placed in view if

2019-03-31 00:22发布

In his answer Richard Peck writes:

Unobtrusive JS

Something else to consider (you've already done this), is that you really need to use unobtrusive javascript in your application.

Unobtrusive JS basically means that you're able to abstract your "bindings" from your page to your Javascript files in the asset pipeline. There are several important reasons for this:

  • 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

It's always recommended you put your JS into separate files - including in the views sets you up for a big mess down the line

This beings me to the following question:

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.

2条回答
干净又极端
2楼-- · 2019-03-31 00:49

The script won't be loaded on every page if it's a Turbolinks app. In Turbolinks your javascript is loaded once, and lives for the entire lifetime of your app. So you would put that page specific script in your main application.js file, and your whole js code (everything in application.js) is basically loaded just once, when the page first loads. If you are using Rails but not using Turbolinks or other ajax techniques (like client side javascript frameworks) then the page specific javascript WILL be evaluated for each request, thus sorta violating DRY like you said and hurting performance.

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

To sum it up Turbolinks is pretty similar to Angular\Backbone\Any most other javascript frameworks in this regard: you basically load the entire javascript code of your application once in your html layout, and no matter what html the user navigated to the javascript code in your application isn't evaluated more than once.

查看更多
爷的心禁止访问
3楼-- · 2019-03-31 00:54

Rails pipeline

It's not Rails pipeline, unobtrusive JS is a standard programming pattern.

Extracting JS from the page ("inline") to an external file cleans up the page, nothing more.

If you want to get the page loaded quickly, you need to split up the JS into separate files. This could be in the form of classes but is mostly for page-specific functionality. For example, you may have admin.js and application.js.


Rails

In regard to Rails specifically, the way to handle unobtrusive JS comes down to how you precompile your assets. The standard way is to put all the functionality into application.js - which will obviously become bloated.

The way around this is to make use of the config.assets.precompile hook - allowing you to specify files you want to include as separately precompiled elements:

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

This is going to change to being handled by manifest.js in Sprockets 4+ (I can explain this in an update if required). I made a commit to their repo about it.

This means that when you precompile the assets (or when you run them in dev -- they're cached), you get admin.js or whatever you defined to be precompiled separately. This means nothing on its own; the files will just appear in public/assets.

What it does mean is that you can then reference the files in your layout:

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

or

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

Thus, you will be able to call the files you need when you need them.

I can go into more depth but this should answer the immediate question.

查看更多
登录 后发表回答