Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js: how to perform garbage collection on parent views as well as child views

Tags:

backbone.js

I have implemented a simple close() method for all the Backbone views which disposes of a view when its not needed/needs to be reset.

Backbone.View.prototype.close = function() {
    if (this.onClose) {
        this.onClose();
    }
    this.remove();
    this.unbind();
};

NewView = Backbone.View.extend({
    el: '#List ul',
    initialize: function() {},
    render: function() {
       _(this.collection.models).each(function(item) {
            this.renderChildren(item);
       }, this);
    },
    renderChildren: function(item) {
        var itemView = new NewChildView({ model: item });
        $(this.el).prepend(itemView.render());
    },
    onClose: function() {
        this.collection.reset();
        // I want to remove the child views as well
    }
});

NewChildView = Backbone.View.extend({
    tagName: 'li',
    render: function() {
    }
});

Now, when I remove the parent view, I also want to remove all the child views here. Any ideas how can I can do this without looping through the models like this....

   _(this.collection.models).each(function(item) {
        item.close();
   }, this);
like image 329
vikmalhotra Avatar asked Nov 04 '11 08:11

vikmalhotra


1 Answers

I think in most of the cases you should keep the view removal in the view layer, without affecting your models.

For example, if you remove a view with comments, maybe another view in your app shows a selection of comments, or some statistics, and resetting the collection would affect those views too.

So I think you should keep it all in the view (only relevant methods included):

NewView = Backbone.View.extend({
    initialize: function() {
       this.childViews = [];
    },
    renderChildren: function(item) {
        var itemView = new NewChildView({ model: item });
        $(this.el).prepend(itemView.render());
        this.childViews.push(itemView);
    },
    onClose: function() {
      _(this.childViews).each(function(view) {
        view.close();
      });
    }
});
like image 178
dira Avatar answered Sep 21 '22 21:09

dira