To my understanding, all of your JavaScript gets merged into 1 file. Rails does this by default when it adds //= require_tree .
to the bottom of your application.js
manifest file.
This sounds like a real life-saver, but I am a little concerned about page-specific JavaScript code. Does this code get executed on every page? The last thing I want is for all of my objects to be instantiated for every page when they are only needed on 1 page.
Also, isn't there potential for code that clashes too?
Or do you put a small script
tag at the bottom of the page that just calls into a method that executes the javascript code for the page?
Do you no longer need require.js then?
Thanks
EDIT: I appreciate all the answers... and I don't think they are really getting at the problem. Some of them are about styling and don't seem to relate... and others just mention javascript_include_tag
... which I know exists (obviously...) but it would appear that the Rails 3.1 way going forward is to wrap up all of your JavaScript into 1 file rather than loading individual JavaScript at the bottom of each page.
The best solution I can come up with is to wrap certain features in div
tags with id
s or class
es. In the JavaScript code, you just check if the id
or class
is on the page, and if it is, you run the JavaScript code that is associated with it. This way if the dynamic element is not on the page, the JavaScript code doesn't run - even though it's been included in the massive application.js
file packaged by Sprockets.
My above solution has the benefit that if a search box is included on 8 of the 100 pages, it will run on only those 8 pages. You also won't have to include the same code on 8 of the pages on the site. In fact, you'll never have to include manual script tags on your site anywhere ever again.
I think this is the actual answer to my question.
You can add this line in your layout file (e.g. application.html.erb) to automatically load the controller specific javascript file (the one that was created when you generated the controller):
You also could add a line to automatically load a script file in a per-action basis.
Just put your page scripts into a subdirectoriy named after the controller name. In these files you could include other scripts using =require. It would be nice to create a helper to include the file only if it exists, to avoid a 404 fail in the browser.
For the page-specific js you can use Garber-Irish solution.
So your Rails javascripts folder might look like this for two controllers - cars and users:
And javascripts will look like this:
and markup_based_js_execution will contain code for UTIL object, and on DOM-ready UTIL.init execution.
And don't forget to put this to your layout file:
I also think that it is better to use classes instead of
data-*
attributes, for the better page-specific css. As Jason Garber have mentioned: page-specific CSS selectors can get really awkward (when you usedata-*
attributes)I hope this will help you.
JavaScripts are only merged when you tell Rails (Sprockets, rather) to merge them.
You can also group the js in folders and continue to use the asset pipeline to load your javascript selectively depending on the page.
Move all your commom JS files to a sub-folder like 'app/assets/javascript/global' then in the application.js, modify the
//= require_tree .
line to//= require_tree ./global
.Now you are free to put your controller-specific JS on the 'app/assets/javascript/' root and they will not be included in compiled JS, being used just when you call them via
= javascript_include_tag
on your controller/view.