Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone Subviews and Event Unbinding

I've been working with Backbone a few days, reading up on design patterns and what have you. Today I was messing with sub-views, after reading a bunch of resources. Primarily, these 2 posts-

Derrick Bailey
http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

Ian Storm Taylor
http://ianstormtaylor.com/assigning-backbone-subviews-made-even-cleaner/

These and others were very useful for helping me set up some subViews and handle their closing in what I thought was a correct pattern:

Backbone.View.prototype.close = function(){
    var ctx = this;
    _.each(ctx.subViews(), function(view) {
        view.close();
    });
    this.remove();
    this.unbind();
}

No problems here, seems to do what I expected. But I wanted to test it, just to see what happened. So I stopped calling close on subViews and looped my render like 20,000 times:

Backbone.View.prototype.close = function(){
    var ctx = this;
    _.each(ctx.subViews(), function(view) {
        //view.close();
    });
    this.remove();
    this.unbind();
}

No zombie event handlers or DOM nodes here. This was a little surprising to me - I'm not an expert in jQuery's internals and I expected to still have the event handlers from the child nodes at least. But I guess because my subViews are all contained within the parent view, which was still being removed and unbound, jQuery clears all the children fine. So I stopped unbinding the parent element:

Backbone.View.prototype.close = function(){
    var ctx = this;
    _.each(ctx.subViews(), function(view) {
        //view.close();
    });
    this.remove();
    //this.unbind();
}

My event handler count in the Chrome inspector still didn't go up.

So my question are:

What is a "real" example of when you need to cleverly handle event unbinding and subViews in this way? Is it any object reference outside of the immediate scope of your View? Is it only if your subviews aren't contained by the parent view's $el?

like image 308
iabw Avatar asked Oct 22 '22 18:10

iabw


1 Answers

When you remove a parent view from the DOM, jQuery does clean up any DOM events that were hooked up in the children. unbind() is an alias for Backbone's Events.off, which removes any events you may have hooked up using myChildView.on('someEvent', ...). For example, a parent view might listen to an event you trigger inside a child view. If you did that, you would need the call to this.unbind() or this.off().

Now that Backbone.Events (as of 0.9.9) has listenTo() and stopListening(), you could consider adding this.stopListening() to your close(). Then if, within your view, you used something like this.listenTo(this.model, ...) they would also be cleaned up properly.

like image 113
Paul Hoenecke Avatar answered Oct 24 '22 11:10

Paul Hoenecke