Search code examples
javascriptmodel-view-controllerevent-delegationmodule-pattern

How to extend event delegation in javascript with module pattern?


I am using module pattern in JavaScript. I have a file say controller.js which handles events. The problem is I want to use sub-modules. But since the events are handled in the controller.js how will I handle the event in the sub-module if any arises?
I dispatch a custom event called PAGE_DISPLAYED from another file say view.js. This event is listened by the controller.js and depending on the displayed page, it does other things, like binding additional event handler specific to that particular page. How to do this using sub-modules.

Sample code:

window.KDJ || (window.KDJ = {});    //namespace
KDJ.controller = (function () {
    $(document).off('PAGE_DISPLAYED');
    $(document).on('PAGE_DISPLAYED', function (e, data) {
    switch(data.pageId) {
    case "page1":
        // do something..
        break;
    case "page2":
        // do something..
        break;
    }
    });

    return {
        // exported methods and props..
    };
})();

How can I extend the above code and the event delegation? Or is the code architecture posing any restrictions.

I am using jQuery Mobile and dispatching the PAGE_DISPLAYED event is done by listening to pagechange event:

window.KDJ || (window.KDJ = {});    //namespace
KDJ.view = (function () {  
    // ...
    $(document).off('pagechange');
    $(document).on('pagechange', function (e, ui) {
        //...
        $(document).trigger(PAGE_DISPLAYED, {'pageId': loadedPageId, 'key': key});
    });
})();

Thanks.


Solution

  • Ok, I tought a few possibilities but in terms of readability the one I like the most is:

    window.KDJ || (window.KDJ = {});    //namespace
    KDJ.controller = (function () {
        $(document).off('PAGE_DISPLAYED');
        $(document).on('PAGE_DISPLAYED', function (e, data) {
    
            //Use the Id if it exsits, if not, try to execute the function
            switch(data.pageId) {
                case "page1":
                    // do something..
                    break;
                case "page2":
                    // do something..
                    break;
                default: 
                    if(data.customFunction)
                        data.customFunction();
                    break;
            }
    
        });
    
        return {
            // exported methods and props..
        };
    })();
    
    
    KDJ.view = (function () {  
        // ...
        $(document).off('pagechange');
    
    
        $(document).on('pagechange', function (e, ui) {
    
            //the function will be executed
            $(document).trigger(PAGE_DISPLAYED, {
                customFunction = function(ui) {
                    console.log("I'm doing something awesome with the ui!");
                }
            });
    
        });
    
        $(document).on('pagechange', function (e, ui) {
    
            //here I'll use the switch
            $(document).trigger(PAGE_DISPLAYED,  {
                'pageId': loadedPageId, 
                'key': key
            });
    
        });
    })();
    

    Here you have another option, without the default. Tell me if one fits your needs :)