Posts Tagged dispatch

Dispatcher followup : A more compact way of writing prototypes + module pattern + test

The previous post I added some prototype methods to the Dispatcher class, but It could has well been written on the following syntax instead

function Dispatcher(){}
Dispatcher.prototype = {
     addEventlistener : function(event, callback){
        //code here
     },
     removeEventlistener : function(event, callback){
        //code here
     }
     //add more methods here... don't forget to comma-separate them and do not add a comma last!
}

So how about writing up this with the module pattern on the same time. I’ll also show a simple way to write an automatic unit-alike test for this.

/**
* @author: Erik Karlsson, www.nonobtrusive.com
**/
var nonobtrusive = nonobtrusive ||{}; //create the "namespace" like object if it doesnt exist
nonobtrusive.events = nonobtrusive.events || {}; //create the sub-namespace events where we'll place our Dispatcher class
nonobtrusive.events.Dispatcher = (function(){
	var undefined; //speed up references to undefined + allows munging
    function Dispatcher(){
         this.events=[];
    }
    Dispatcher.prototype = {
		addEventlistener : function(event, callback){
			if ( event == undefined || callback == undefined ) return false;	//verify that we have parameters sent in
			var listeners = this.events[event] = this.events[event] || [];		//create a new array to hold listeners if first time
			listeners[listeners.length]=callback;
		},
		removeEventlistener : function(event, callback){
			if ( event == undefined || callback == undefined ) return false;	//verify that we have parameters sent in
			var listeners = this.events[event];
			if ( listeners ) {
				for ( var i = listeners.length-1; i>=0; --i ){	//go through all listeners for this specific event
					if ( listeners[i] === callback ) {
						listeners.splice( i, 1 );	//remove the eventcallback if we found it
						return true;
					}
				}
			}
			return false;
		},
		dispatch : function(event){
			if ( event == undefined ) return false;
			if ( this.events[event] ) {
				var listeners = this.events[event], len = listeners.length;
				while ( len-- ) {
					listeners[len](this);	//callback with self
				}		
			}
		}
		//add more methods here... don't forget to comma-separate them and do not add a comma last!
   }
 
   return Dispatcher;
})();
 
 
function DispatcherTest(){
	nonobtrusive.events.Dispatcher.call(this);
 
	//Some internal variables to keep track of the test-process.
	var	dispatchOk = false,
		afterRemovalOk = false;
 
	this.dispatchCallback = function(){
		dispatchOk = !dispatchOk;
	}
 
	this.setup = function(){
		this.addEventlistener("TestEvent", this.dispatchCallback);
	}
 
	this.run = function(){
		this.dispatch("TestEvent");
		afterRemovalOk = this.removeEventlistener("TestEvent", this.dispatchCallback);
		this.dispatch("TestEvent");	//nothing should happen since we're not listening to this event anymore.
		if ( dispatchOk && afterRemovalOk ) {
			alert("DispatcherTest was ok!");
		}
	}
}
DispatcherTest.prototype = new nonobtrusive.events.Dispatcher();
 
//Run the test
var test = new DispatcherTest();
test.setup();
test.run();

If you want to use this class, download the minified script here :
http://www.nonobtrusive.com/wp-content/uploads/2009/07/nonobtrusive.events.Dispatcher-min.js
or try out the test yourself by visiting this page :
http://www.nonobtrusive.com/wp-content/uploads/2009/07/dispatcher-test.html

, , , , ,

No Comments