I'm developing a jQuery application for a website and by what I have read, the module pattern seems to be the best setup.
I've begun to adapt the module/sub module pattern and before I write the application, I'm wondering if the development is correct. Here is a basic sample:
var module = (function($, window, document, undefined) {
return {
loader : (function() {
var fade = 250; // public property
var $loader = $('#loader'); // private property
// return public properties and methods
return {
fade : fade,
show : function() {
$loader.fadeIn(module.loader.fade);
},
hide : function() {
$loader.fadeOut(module.loader.fade);
}
}
})()
}
})(jQuery, window, document);
module.loader.fade = 500;
module.loader.show();
Again, "loader" would be a sub module. I want to keep all my sub modules wrapped in the main module.
I'm wondering if I'm handling the public property correctly, or if there is a better way?
Thanks
Your IIFE is aware of the var module on line 1 because its show and hide methods are referencing module.loader.fade. That is not good. A properly written IIFE should have all dependencies passed in via arguments. In this example, if you changed the name of the variable from "module" to "module2", you'd have to change the body of your IIFE. A properly written IIFE does not have this problem.
You're also using a variant of the Revealing Module Pattern to expose the closure variable fade. I'm going to refrain from speaking ill of this widely accepted antipattern and simply point out two better alternatives below.
The first alternative uses this to reference the fade variable.
var module = (function($, window, document, undefined) {
return {
loader : (function() {
var fade = 250; // public property
var $loader = $('#loader'); // private property
// return public properties and methods
return {
fade : fade,
show : function() {
$loader.fadeIn(this.fade); // use this
},
hide : function() {
$loader.fadeOut(this.fade); // use this
}
}
})()
}
})(jQuery, window, document);
module.loader.fade = 500;
module.loader.show();
The second alternative creates a reference to the returned object.
var module = (function($, window, document, undefined) {
return {
loader : (function() {
var fade = 250; // public property
var $loader = $('#loader'); // private property
var stub;
// return public properties and methods
return stub = {
fade : fade,
show : function() {
$loader.fadeIn(stub.fade); // use return object to reference fade
},
hide : function() {
$loader.fadeOut(stub.fade); // use return object to reference fade
}
}
})()
}
})(jQuery, window, document);
module.loader.fade = 500;
module.loader.show();
It looks like you'd be in the right to do it either way. This post suggests you can use a self-calling function for a sub-module: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html#submodules. The only difference being that the submodule in this case is added following the creation of its parent module.
Another good overview of the module pattern and namespacing in general if you haven't stumbled on it yet: http://javascriptweblog.wordpress.com/2010/12/07/namespacing-in-javascript/. Of particular note are the idea that you can leave your context as a parameter for the Self-invoking function.
As an aside -- as your module and project architecture develop more, you might consider require.js for module management.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With