unobtrusive jquery and rails
I have been a fan of UJS for the longest time and I usually put ALL my code in application.js(jquery, not prototype)
However, I have come across a huge project that will bloat up application.js if left untended and I don't want that to happen, especially since most of my functions/behavior will be based on specific pages. Right now, I am inclined to put the javascript calls on specific partials, like so:
on _test_partial.html.haml:
%p= link_to "Expand All", '#', :class => "expand-categories"
:javascript
$(function() {
$('.expand-categories').click( function() {
$(".test-cases").slideToggle();
return false;
})
})
Or if I really wanted "unobtrusive" stuff:
%p= link_to "Expand All", '#', :class => "expand-categories"
= javascript_include_tag 'test-categories.js'
But it seems to me that this is still very obtrusive, as if I have to edit the code/behavior, I will have to look for the partial concerned. On the other hand, isn't that easier that scouring a 1MB(there are lots of pages and there will probably lots of page specific code) application.js of a function i need to edit.
What's the usual take on this? Is there a way for me to开发者_JAVA技巧 name a js file ala RJS like test_partial.js.erb os something?
I personally try to keep all my javascript under public/javascript as much as possible. However I break my application.js file into multiple files based on "sub-domains", e.g. application.profiles.js, application.albums.js, etc... with each file implementing the Module Pattern. This approach allows you to nicely compartmentalize your javascript code, load it as needed and I believe addresses your concern of being able to quickly find functions.
Given one file or "sub-domain" (e.g. application.profiles.js), you can further compartmentalize your code using the "Augmentation Pattern" described in this article. So you may end up with something like application.profiles.core.js and application.profiles.viewer.js, where for example, the application.profiles.viewer.js module augments the application.profile.core.js module.
Hope this helps.
Lately I have been utilizing data param a lot, as rails.js already does. So, if I have something like your issue I place script either in application.js or, in case it's a complex project, in one of the JavaScript "classes" (will explain later).
%p= link_to "Expand All", '#', :"data-action" => "expand-categories"
and
// application.js
$('[data-action="expand-categories"]').bind('click', expand_categories);
As for usage pattern, I create javascript files logically separated for each part of the application. So far separate files for front and back-end have been enough for me, but it can be used for per feature pattern. It's a rather complex pattern but easy to maintain and it goes something like this (using head.js):
// application.js
head(function () {
if ($([data-action="expand-categories"]).length) {
var expand_categories = new ExpandCategories();
expand_categories.init();
}
}
...
// expand_categories.js
var ExpandCategories;
ExpandCategories = function(){
var self;
self = this;
self.init = function(){
/*
* This is something like public method.
* Use it to call some private method depending on some condition
*/
// no need to check for existance, we did it on application.js
var expand = $('[data-action="expand-categories"]');
if (expand.text("some specific text")) {
expand.live('click', expand_categories);
}
}
var expand_categories(){
// This is something like "private" method
// ... expand categories
}
}
精彩评论