Search code examples
jquerybackbone.js

Memory leak deleting backbone view


When executing the following code the Collection View is not completely deleted. currentView.remove(); and currentView.unbind(); does not remove & unbind the entire view within its model views. What do I need to do to delete collection view + model view? (reset is no option)

var Coll_Item = .. //contains collection within models

var currentView = new DiagnoseApp.Views.Coll_Item({collection: Coll_Item}); 
currentView.remove();
currentView.unbind();

(I took heap-snapshots with google-chrome and whenever the code is executed the heap grows.)

Collection View:

DiagnoseApp.Views.Coll_Item = Backbone.View.extend({
    initialize: function(){
        this.collection;
    },
    render: function(){
        this.addAll();
    },
    addAll: function(){
            this.$el.html($('<table id="whatever" />'));
            this.collection.each(this.addOne, this);             
    },
    addOne: function(Param){
            var tbodyView = new DiagnoseApp.Views.item({model: Param});
            this.$el.find('#whatever').append(tbodyView.el);
    }
});

Model View:

DiagnoseApp.Views.item   = Backbone.View.extend({
    newTemplate: _.template($('#item-template1').html()),
    initialize: function () {
        this.render();
        this.model.on('change', this.render, this);
    },
    render: function () {
         this.$el.html(this.newTemplate( this.model.toJSON() ));
    },
    events: {
        'blur .edit' :      'editParam',
        'keypress .edit' :  'updateOnEnter'
    },
    updateOnEnter: function (e){
        if (e.which == 13){
          this.editParam();
        }
    },
    editParam: function(){
         var newValue = this.input.val().trim();
         this.model.set('val', newValue);
    }
}); 

Solution

  • Dominic has the right answer, but if you need more details: In your code the statement

    this.model.on('change', this.render, this);
    

    causes the model to store a reference to the view. So long as the model exists, that reference will still be there and JavaScript will have to keep a copy of the view around just in case the model tries to do something with it.

    If, instead, you change your code as Dominic suggests:

    this.listenTo(this.model, 'change', this.render);
    

    Then the model will no longer retain a reference to the view. In that scenario, deleting the view is safe and the JavaScript engine will release the memory when the view is deleted.