Search code examples
backbone.jsforeachunderscore.jsparent-childbackbone-views

Backbone child view removal infinite loop


I am trying to remove all child views in Backbone by modifying the Backbone.View.prototype like this:

_.extend(Backbone.View.prototype, {
childViews:[],
close: function(){
    this.remove();
    this.unbind();
    console.log(this.childViews.length);
    _.each(this.childViews,function(childview){
        childview.close();
    },this);
}
});

So when I create a child view, I push to childViews. When I close I expect it to also call close on the childViews. If it has nothing in childViews, then I expect the chain of close to stop. fiddle

What ends up happening is some sort of infinite loop. I can't figure out why it is behaving like this. Is it a problem with _.each's [context]? Can someone explain what I am doing wrong and how to fix this?


Solution

  • Your problem is that you've added childViews: [] to the prototype. That means that every single view instance will share exactly the same childViews array. Once you have any child views anywhere, you will end up with this.childViews containing this and there's your infinite loop.

    Instead, you should create childViews in the view's initialize:

    initialize: function() {
        this.childViews = [ ];
        //...
    }
    

    You might have to update your close method to allow for an undefined this.childViews as well.

    Updated fiddle: http://jsfiddle.net/ambiguous/f2ykv/


    As a rule of thumb, you almost never want any mutable properties (such as arrays or objects) attached to the prototype, you almost always want those properties assigned per-instance.