Reputation: 6274
I'm trying to get the hang of the whole asset pipeline thing, and read the guide and several tutorials about them. But one thing that doesn't become quite clear is wether I should view my javascript asset files as a library or a place to put code that is actually run i.e. $(document).ready. Because by default all the javascript files are included, and it would be weird to have several $(document).ready's in there, not to mention that you don't want the $(document).ready function for every page to be run in the first place. What would be the way to go at this? Use my asset files as a library and put actual calls in my views (ugly)? Or is there a better way to do this?
Upvotes: 2
Views: 451
Reputation: 1801
I too ran into this issue. In a large project you can have somebody put code into document ready to, for example, add a click function to each li within a div with class container.
Now we could all argue that the above code would be too generic and of course may affect li tags in other parts of the application, but the bigger the project, the more likely it is that you will run into a conflict like this leading to unexpected behaviour.
I for one am uncomfortable with a whole bunch of document ready functions running for each and every page loaded. My solution is not necessarily the perfect one, but it's one that I have taken up and will share with you.
In the body tag of each page I add data elements signifying the controller and the action. I then have one document ready script that looks for a class named after the controller with the name Ready appended e.g. HomeReady. It will then call a method on this class (presuming it exists) named after the action. So in your asset coffee file you could write:
class @HomeReady
@index: ->
alert("Hello")
@show: ->
alert("Goodbye")
This allows control right down to the action level. When I came across your question I decided to package this solution into a gem as I have already used it in several projects. You can find it at: https://github.com/intrica/rails_document_ready
Upvotes: 1
Reputation: 4807
If you absolutely don't want a certain piece of initialization code to be run unless the current page is a specific controller/action, then you can try adding an empty element on the page with an id built from that info like "posts_index" using these two helpers:
"#{controller_name}_#{action_name}"
Then in your javascript you can wrap the code inside an if statement that checks for the existence of an element with the appropriate id.
edit: Here's an example of the js partial that I mentioned in the comments.
show.html.haml
= render 'map'
map.html.erb
(I normally use haml but it's easier to write js in erb)
<script src='http://www.google.com/jsapi' type='text/javascript'></script>
<script type='text/javascript'>
...
</script>
It's probably not as clean as it could be and it doesn't get the benefits of being part of the asset pipeline but I don't mind because it's only something that gets included on a specific page.
Upvotes: 0