Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct jQuery Application Module Pattern

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

like image 533
Andrew Bessa Avatar asked Mar 13 '26 13:03

Andrew Bessa


2 Answers

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();
like image 179
I-Lin Kuo Avatar answered Mar 16 '26 02:03

I-Lin Kuo


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.

like image 30
ossek Avatar answered Mar 16 '26 02:03

ossek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!