Decorate a method with Dojo

Posted by Mike on Oct 2nd, 2008

Here’s a quick example of how to incorporate the Decorator Pattern into your javascript code using the Dojo framework. Rather than decorating an entire class, this example merely decorates a single function, extending the original function with some extra logic.

// Instantiate widget class
var w = new core.widget.MyWidget();
 
// Decorate the original "method1" function
var _old_method1 = dojo.hitch(w, w.method1);
w.method1 = function(param) {
    var out = _old_method1(param);
 
    // Decorations
    if (param == 'foo' || out == 'bar') {
        console.log('calling method2 as result of method1');
        this.method2('baz');
    }
};

A few key points:

  • dojo.hitch – used to provide proper context to the base “method1″, so that if anything relies on “this.” it will be handled as expected
  • The decorations can be applied either before or after the base method is called. In the example, I chose to apply them after the base method to enable reaction based on the output.

You may notice that this is a much uglier implementation than the coffee and condiments example in the linked Wikipedia article. The wrap-add-and-return methodology didn’t work for me due to some class complexities and black magic. There may be a better way, perhaps even built into the dojo class wizardry, but this fit my use case well enough.

A coworker pointed out that Dojo now has the fancy shmansy dojox.aspect package to deal with this. And I found a great article detailing the new aspect wizardry in dojo. So my example could be revised using AOP, as follows.

// Instantiate widget class
var w = new core.widget.MyWidget();
 
// Create an aspect to wrap the method
dojo.require("dojox.lang.aspect");
var aop = dojox.lang.aspect;
aop.advise(w, 'method1', {around: function(param){
    var out = aop.proceed(param);
 
    // Decorations
    if (param == 'foo' || out == 'bar') {
        console.log('calling method2 as result of method1');
        this.method2('baz');
    }
}});
  • Twitter
  • Facebook
  • StumbleUpon
  • Google Reader
  • Reddit
  • Share/Bookmark

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Categories