Dispatcher / EventAggregator update
Earlier I posted an implementation of EventAggregator for Backbone.js. Please read that first.
Tracking down bugs in an EDA setup can be tough. This one had me going crazy.
I had forgotten to take into consideration Backbone.js's behavior regarding events being triggered inside a Model which is:
If a model is a member of a collection, all events triggered in that model will also be triggered on the collection.
This is handy - and dangerous. To keep this behavior and prevent my Event Aggregator implementation from double-firing the same event,
a small fix needed to be inserted. Note the check below for isEligibleForDispatcher:
BackboneExt {...
dispatcher : _.extend({}, Backbone.Events, { cid : 'dispatcher'}),
wrappedEvents : function (localEvents) {
var local = localEvents || _.extend({}, Backbone.Events);
var isEligibleForDispatcher = function (source) {
return !((source instanceof Backbone.Model) && (source.collection instanceof Backbone.Collection));
}
//note that 'this' is the Backbone implementation
return {
dispatcher : BackboneExt.dispatcher,
trigger : function () {
BackboneExt.trigger('wrappedEvents:triggered', this);
// this._callbacks is an internal collection
// currently backbone could
if (this._callbacks) {
local.trigger.apply(this, arguments);
}
if (isEligibleForDispatcher(this)) {
//we must call dispatchers trigger with the dispatcher as 'this''
//otherwise, the wrong collection will be queried for _.callbacks
BackboneExt.dispatcher.trigger.apply(BackboneExt.dispatcher, arguments);
BackboneExt.trigger('dispatcher:triggered', this);
}
return this;
}
};
},
extendBackbone : function () {
var self = this;
if (self.isExtended) {
return;
}
_.each(backbonePrototypes, function (proto) {
_.extend(proto, self.wrappedEvents());
});
}
Backbone events : being careful
In general, I avoid triggering events from my initialize methods on my models. I have found that when I do so, the event is not fired on the collection. So if there are other objects that bind to my dispatcher they will not receive these events if they are fired inside a Model.initialize method.
Posted
10-20-2011 3:02 PM
by
Michael Nichols