dojo/on
and dojo/aspect
are two APIs that appear to do similar jobs but actually serve two different purposes.dojo/on
is used to setup event listeners for DOM nodes and event-emitting objects.dojo/aspect
provides Aspect Oriented Programming facilities so functionality can be run before,after,or around a method call and can even manipulate the input to the original method or the original method’s output.
dojo/on
dojo/on
is the general purpose event module and can be used to listen for events on DOM nodes and event-emitting objects. The most basic use is to set up an event listener on an element directly or to use event delegation.
require([ 'dojo/on','dojo/query' ],function(on) { varactionButton = document.getElementById('actionButton'); // add event listener directly to a DOM Node on(actionButton,'click',function() { console.log('button clicked'); }); // use event delegation to listen for events on(document,'.button:click',function () { console.log('button clicked'); }); }); |
dojo/on
can also be used to set up listeners for events emitted from objects that inherit fromdojo/Evented
. These objects gain an emit
method,which can be used to trigger a custom event.
require([ 'dojo/_base/declare','dojo/Evented','dojo/on' ],function(declare,Evented,on) { varMyClass = declare(Evented,{ run:function () { this.emit('custom-event',{ name:'world' }); } }); varc = new MyClass(); on(c,'custom-event',function (data) { console.log('hello,'+ data.name); }); c.run(); }); |
dojo/aspect
On the other hand,dojo/aspect
can be used in a number of ways to run code before,or around a method call. For example,if we have arand
object that has a method getNumber
which returns a random number in a given range,we can useaspect.after
to call a new method after the original method is executed and change the return value to be a little less random:
var div = document.querySelector('#result'),after = document.querySelector('#after'); require([ 'dojo/aspect' ],function(aspect) { varrand = { getNumber:function (min,max) { returnMath.floor(Math.random() * (max - min + 1)) + min; } }; aspect.after(rand,'getNumber',function (value) { console.log('actual result '+ value); return4; }); console.log('returned result '+ rand.getNumber(3,10)); }); |
Similarly,we could use aspect.before
to execute code before getNumber
is called and return an array,changing the arguments that are passed to the original function:
require([ 'dojo/aspect' ],max) { returnMath.floor(Math.random() * (max - min + 1)) + min; } }; aspect.before(rand,function (min,max) { console.log('original arguments: '+ min + ',' + max); return[6,16]; }); console.log('returned result: '+ rand.getNumber(20,30)); }); |
Finally,aspect.around
can be used to return a function to replace the original method. This new method can then conditionally call the original method if necessary:
require([ 'dojo/aspect' ],max) { console.log('original method called'); returnMath.floor(Math.random() * (max - min + 1)) + min; } }; aspect.around(rand,function (origMethod) { returnfunction (min,max) { if(min === max) { console.log('not calling original method'); returnmin; } // only call the original method if min !== max returnorigMethod(min,max); }; }); console.log('returned result: '+ rand.getNumber(20,20)); }); |
As you can see,dojo/on
is a useful utility for listening for events from the DOM or event-emitting objects,whiledojo/aspect
is useful for injecting code before,or around the original method call.