Styles

Tuesday, May 27, 2014

Javascript's Decorator Pattern using Require.js

While working at Mi9 I stumbled across a very interesting way to use the Javascript Decorator Pattern in order to separate the concerns of the html and the way it populates information using the require.js framework.

For those of you who are unfamiliar to require.js, I have provided an extremely simple example below. It is basically a simple lightweight framework that helps you load javascript files on demand. Each of these files provides a module that can introduce features to your javascript functionality.

A simple example of require.js is can be shown below when you specify a module in the require construct, which uses dependency injection to pass in the helper service and its members:

    require(['jquery', './helper'], function ($, helper) {
        var callSingleStoryService = function (url) {
            $.get(url, function (data) {
                helper.evaluateElapsedTime(data);
            });
        };
        return {
            decorate: function (data) {
                callSingleStoryService(data);
            }
        };
    });

This will locate the helper file located relatively in ./helper, and the actual helper module provides the functionality for evaluateElapsedTime(data); as shown below:

    define(['jquery'], function ($) {
        return {
            evaluateElapsedTime: function (element) {
                //do stuff...
            }
        };
    });

This is just a simple example of how to use require.js.

Now, to apply this to an html element in order to provide a decorator to its inner elements, you can provide the following attributes as follows in your view:

    <div class="module" data-module="./feedDecorator">
        <div class="block">
            <div class="grid">
                Some content...
            </div>
        </div>
    </div>


The above html tells the application to associate the feedDecorator.js file which has a decorate function in it to apply functionality to this specific element with a "module" class name. Your feedDecorator.js file will look like the following:

(function () {
    define(['jquery', './helper'], function ($, helper) {
        return {
            decorate: function ($target, data) {
                helper.evaluateElapsedTime($target, data);
            }
        };
    });
});

How does it all work? Your main.js (the only js file that you need to initially load) should implement the following functionality that will go through each element with the class name "module" and run its respective "decorate" function, which is simply associated by the module specified in the "data-module" html attribute.

(function() {
  define(['require', 'jquery'], function (require, $) {
    var decorator = function ($target) {
      var moduleName = $target.dataset['module'];
      require([moduleName], function (module) {
        var data;
        if ($.isFunction(module.decorate)) {
          data = $target.data();
          delete data.module;
          return module.decorate($target, data);
        }
      });
    };
    function () {
        $(".module").each(function () {
          return decorator($(this));
        });
    };
  });
});

And its as simple as that! Now for any specific html element, you can associate specific javascript functionality to apply to it without having to load large amounts of javascript files unnecessarily.



8 comments :

Yousufzai said...

I want to start a blog written by a fictitious character commenting on politics, current events, news etc..How?. website designers nyc

julie lars said...

An fascinating dialogue is value comment. I feel that it’s best to write extra on this matter, it may not be a taboo topic however usually people are not enough to speak on such topics. To the next. Cheers new york web designs

Anonymous said...
This comment has been removed by the author.
Anonymous said...
This comment has been removed by the author.
sdexter said...

Its amazing what supplementing can do for your body and your weight lifting goals! branding sf

william locas said...

Water-resistant our wales in advance of when numerous planking. The particular wales surely are a selection of heavy duty snowboards that this height ones would be the same in principle as a new shell planking having said that with much more height to help you thrust outward in the evening planking. planking design agency san francisco

julie lars said...

You completed a number of nice points there. I did a search on the issue and found nearly all people will have the same opinion with your blog. iphone template

keivi jhons said...

LCD TVs can really save you from high electricity bills and office space~ design firms los angeles