THE BLOG

News, tips and tricks from 2Gears

ExtJS Global eventmanager with destroy catcher

Posted · Add Comment

In my applications I like to have a global eventmanager that can be instructed to listen to certain events and call registered event handlers. Jonathan Julian proposed an elegant way of creating a global eventmanager by creating an instance of Observable. This works for the most part… if you don’t destroy any listeners runtime.

 

 

Normally the eventmanager would be created like this this:

// Create the global event manager
MyApp.eventManager = new Ext.util.Observable();

// Tell the event manager to which it events it should listen
// and allow subscribers to hook in to
MyApp.eventManager.addEvents(
    'selectnode',
    'someotherevent'
);

The global event manager can then be used by components to fire events on, thus signaling subscribers to the event, or subscribe to certain events themselves.

// Somewhere in a tree click handler
// a tree node object is passed to possible event handlers that are listening
MyApp.eventManager.fireEvent('selectnode',node);

...

// A grid somewhere else should refresh it's store on the above event
// Here the MyGrid instance has a 'refreshHandler' function
MyApp.eventManager.on(
    'selectnode', // the event
    myGrid.refreshHandler.createDelegate(myGrid)
);

The above publish-subscribe method works like a charm but sometimes fails. The eventManager is passed a reference to a function of a component, in this case function ‘refreshHandler’ of component ‘myGrid’. If the ‘myGrid’ component is destroyed (removed from a parent with autoDestroy true), the (now defunct) reference to the handler function still exists in the global eventManager list of subscribers and causes a javascript error to occur when the event is triggered; a function of a non-existent object is called.

The above can be fixed by extending the Observable class. The extended class makes sure that when an object is destroyed (firing it’s destroy event), any event handlers that might be a part of the object are removed from the list of subscribers.

MyApp.eventManager = Ext.extend(Ext.util.Observable, {
	addListener: function(eventName,handler,scope,options) {
		if (scope) {
			scope.on({
				scope:this,
				beforedestroy: function() { //create closure
					this.removeListener(eventName,handler,scope);
				}
			});
		}

		MyApp.eventManager.superclass.addListener.apply(this, arguments);
	}
});

Hope it helps anyone

Rob

Leave a Reply

Your email address will not be published. Required fields are marked *

13 − 12 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>