2014-11-08 21 views
2

刪除老款我已經創建了簡單的例子http://jsfiddle.net/n7tntcb5/從內存

$ (function() { 
'use strict'; 

var ButtonView = Backbone.View.extend ({ 
    tagName : 'button', 

    events : { 
     'click' : 'onClick' 
    }, 

    initialize : function (options) { 
     this.collection = options.collection; 
    }, 

    render : function() { 
     this.$el.html ('Click'); 
     return this; 
    }, 

    onClick : function (event) { 
     this.collection.reset ([ 
      { "id" : _.random (0, 1000), data : new Array (100000).join ('a') }, 
      { "id" : _.random (0, 1000), data : new Array (100000).join ('a') }, 
      { "id" : _.random (0, 1000), data : new Array (100000).join ('a') } 
     ]); 
    } 
}); 

var ListView = Backbone.View.extend ({ 
    tagName : 'ul', 

    initialize : function (options) { 
     options || (options = {}); 

     this.views = []; 
     this.collection = options.collection; 

     this.listenTo (this.collection, 'reset', this.render); 
    }, 

    empty : function() { 
     _.each (this.views, function (view) { 
      view.remove(); 
     }); 

     this.$el.empty(); 
    }, 

    render : function() { 
     this.empty(); 

     this.collection.each (function (model) { 
      var view = new ListItemView ({ model : model }); 
      this.views.push (view); 
      this.$el.append (view.render().el); 
     }, this); 

     return this; 
    } 
}); 

var ListItemView = Backbone.View.extend ({ 
    tagName : 'li', 

    initialize : function (options) { 
     options || (options = {}); 

     this.model = options.model; 
     this.collection = options.collection; 

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

    render : function() { 
     this.$el.html (this.model.get ('id')); 
     return this; 
    }, 

    remove : function() { 
     if (this.model) { 
      //this.model.clear(); 
      delete this.model; 
     } 
    } 
}); 

var Model = Backbone.Model.extend ({ 
    defaults : { 
     id : null, 
     name : '', 
     data : '' 
    } 
}); 

var Collection = Backbone.Collection.extend ({ 
    model : Model, 

    parse : function (response, options) { 
     return response.models || response; 
    } 
}); 

var collection = new Collection(); 
var list = new ListView ({ collection : collection }); 
var button = new ButtonView ({ collection : collection }); 

$ ('body') 
    .append (list.render().el) 
    .append (button.render().el); 
}); 

在「骨幹眼」的Firefox插件或Chrome的「骨幹調試器」我看到的模型數量不斷與每一個按鈕的點擊增長。我如何從舊物體中釋放記憶?

回答

3

您的empty函數並沒有清理所有的東西。當然,你打電話removethis.views的一切,但你永遠不會清空views陣列。試試這個版本:

empty: function() { 
    _.each(this.views, function(view) { 
     console.log(view.cid) 
     view.remove(); 
    }); 

    this.$el.empty(); 
} 

和看控制檯當您點擊按鈕幾次:http://jsfiddle.net/ambiguous/27b15fsr/

ListView與日益增長的在其views陣列ListItemView引用和那些殭屍意見將數組結束了引用了會提及模型的集合。你需要插入此泄漏:

empty: function() { 
    _.each(this.views, function(view) { 
     view.remove(); 
    }); 
    this.$el.empty(); 
    this.views = [ ]; // <------ 
} 

BTW,你不需要做這在你看來initialize方法:

this.collection = options.collection; 

骨幹將討論通過自身;從fine manual

構造函數/初始化new View([options])

有跡象表明,如果獲得通過,將直接連接到視圖幾個特殊選項:modelcollectionelidclassNametagNameattributesevents

+0

哦,我忘了清空this.views!謝謝你,畝,非常多( - : P. S.'this.collection = options.collection;'只是爲了清楚,謝謝( - : – yanot 2014-11-09 09:14:54