Backbone Events and Aggregator Update

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

[Advertisement]

Comments

viikram wrote re: Backbone Events and Aggregator Update
on 11-18-2011 5:13 AM

In your implementation of eventaggregator, I am stuck at the point where two views subscribe to an event triggered by some other (third) view. Now when I want to discard one  of the subscribers and try to unbind the event, both the subscriber views are unsubscribed from the event. I use this code to unbind from an event:

Backbone.dispatcher.unbind('select:left');

Is there some fix/workaround for this?

Michael Nichols wrote re: Backbone Events and Aggregator Update
on 11-18-2011 8:34 AM

It seems like you have two choices: 1) Include some kind of context object as the first arg (similar to the (e.target) of the jQuery event object) and do a test against that. 2) Bind the views to a different, local event and have the dispatcher bound to a method that simply triggers that event.

#2 would be my preference.

viikram wrote re: Backbone Events and Aggregator Update
on 11-22-2011 1:29 AM

I finally found the solution by digging a little into the Backbone code.

Here's how I was binding the events:

Backbone.dispatcher.bind('select:left', this.handleSelectLeft);

Here's how I unbind them now....

Backbone.dispatcher.unbind('select:left', this.handleSelectLeft);

The key was while unbinding the event I wasn't unbinding the handler which is what I wanted.

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)