2013-01-20 54 views
3

我有一個過濾器,用於處理我的骨幹網絡集合。在搜索框和列表中輸入實時過濾條件。偉大的作品,或者我想過的。當我查看chrome中的內存堆快照時,我可以看到每次搜索都會泄漏內存...... 6個8 megs ...不久之後,堆快照爲100多個megs。過濾骨幹集合時發生內存泄露

我在下面的視圖中隔離了這個問題。如果我在初始化函數中註釋掉this.listenTo,我似乎不再泄漏內存。

所以我的問題是如何保持這些事件監聽器和集合上的實時過濾而不會泄漏。

var View = Backbone.View.extend({ 

    tagName: 'tr', 

    initialize: function() { 
     this.listenTo(this.model, 'change', this.render); 
     this.listenTo(this.model, 'destroy', this.remove); 
    }, 

    events: { 
     'click .edit': 'edit', 
     'click .delete': 'delete', 
    }, 

    edit: function() { /* EDIT */ }, 

    delete: function() { 
     this.model.destroy(); //backbone 
    }, 

    render: function() { 
     var template = _.template(ProductTemplate) 
     this.$el.html(template({ this.model.toJSON() })) 
     return this; 
    } 

}) 


var ListView = Backbone.View.extend({ 

    initialize: function() 
    { 
     this.collection = new Collection(Products) //products are bootstrapped on load 
    }, 

    render: function (terms) 
    { 
     this.$el.html(ListTemplate); 

     var filtered = Shop.products.collection.search(terms) 

     _.each(filtered, this.addOne, this) 

     //append list to table 
     $('#products').html(this.el) 

     return this 
    }, 

    addOne: function (product) 
    { 
     this.$el.find('tbody').append(
      new View({ model: product }).render().el 
     ) 

     return this 
    }, 

}); 

var Collection = Backbone.Collection.extend({ 

    model: Model, 

    search : function(letters){ 

     //set up a RegEx pattern 
     var pattern = new RegExp(letters,"gi") 

     //filter the collection 
     return this.filter(function(model) 
     { 
      if(letters == "") return true //if search string is empty return true 
      return pattern.test(model.attributes['Product']['name']) 
     }); 
    } 


}); 

解決:

這是我的新的搜索方法。我不再過濾收集和重新渲染。我簡單地遍歷集合,如果一個模型匹配搜索,我們觸發一個'show'事件,如果它不在搜索中,我們觸發一個'hide'事件。然後,我們在視圖中訂閱這些事件並採取相應行動。從集合

搜索功能: 搜索:功能(查詢){

//set up a RegEx pattern 
    var pattern = new RegExp(query,"gi") 

    //filter the collection 
    this.each(function(model){ 
     if (pattern.test(model.attributes['Product']['name'])){ 
     model.trigger('show') 
     } 
     else{ 
     model.trigger('hide') 
     } 
}); 
} 

新觀點: VAR的ProductView = Backbone.View.extend({

tagName: 'tr', 

    initialize: function() { 
     this.listenTo(this.model, 'show', this.show); 
     this.listenTo(this.model, 'hide', this.hide); 
    }, 

    hide: function() 
    { 
     this.$el.addClass('hide') 
    }, 

    show: function() 
    { 
     this.$el.removeClass('hide') 
    }, 

    render: function() 
    { 
     var template = _.template(ProductTemplate) 
     this.$el.html(template({data: this.model.toJSON(), Utils: Shop.utils})) 
     return this; 
    } 

}); 
+2

因此,你創建了很多'View'實例,但從來沒有調用'remove'對他們? –

+0

所以我知道我的問題是我創造了無盡的意見,並永遠不會關閉它們。我只是試圖想出一個跟蹤觀點的好方法,以便我可以關閉它們。或者像下面的@anshr建議的那樣,根據查詢簡單地隱藏/顯示它們。到目前爲止,這樣的方法已經沒有了。 –

回答

4

爲了擴展@mu已經評論過,你並沒有移除你創建的視圖,他們不在DOM中,但是他們仍然在內存中閒逛,因爲他們有一個對你的模型的引用(因此,垃圾收集器不會爲你刪除它們)。

你有幾個選擇:

  1. 的正在由addOne實例化,每次render被稱爲刪除所有意見跟蹤。
  2. 使您的代碼顯示/隱藏視圖,而不是在每次更改過濾條件時都實例化/銷燬。這是更多的工作,但肯定是更優化的解決方案。
+0

謝謝。我已根據上述答案更新了我的問題。 –