2013-03-01 34 views
4

更新: 根據我的評論,我的問題是,我有一個額外的模型,我傳遞到視圖中,我並未解除綁定事件。當我看到事件處理程序被觸發時,我認爲源是來自this.model而不是this.extra_model,因爲我忘記了這個.extra_model也被用於錯誤驗證。殭屍事件仍然在移除骨幹視圖後

解決的辦法是添加以下內容:

MyView = Backbone.extend({ 
    //... 
    //add method to override BaseView 
    cleanUp: function() { 
    this.extra_model.off(null, null, this); 
    BaseView.prototype.cleanUp.apply(this, arguments); 
    }, 
    //... 
}); 

感謝審查的問題,併爲程序員錯誤抱歉。


所有: 我在與我已經清理了一個視圖後,仍然被束縛陳舊/殭屍事件的問題。當我將自定義事件綁定到模型時,問題就出現了。當我從dom中刪除視圖時,我調用'this.model.off(null,null,this);'正如在各種消息板上所建議的,但儘管我可以在chrome調試器工具中看到「自定義處理程序」回調被刪除,但我仍然注意到「自定義處理程序」的事件處理程序被調用的次數比它應該多(每個額外的一次當我清理它時重新創建視圖)觸發事件時。有人能告訴我,如果我的清理代碼丟失了什麼?提前致謝!

BaseView = Backbone.extend({ 
//... 
     displayErrors:function(){}, 

     cleanUp: function(){ 
     if (this.model) this.model.off(null, null, this); 
     if (this.collection) this.collection.off(null, null, this); 
     if (!this.options.persistDataAfterViewCleanup) { 
      if (this.model) delete this.model; 
      if (this.collection) delete this.collection; 
     } 
     //_.each(this.subViews, function(view){view.cleanUp();}); not needed yet. 
     this.undelegateEvents(); 
     $(this.el).removeData().unbind(); 
     //Remove view from DOM 
     this.$el.html(''); 
     this.remove(); 
     } 
}); 

MyView = BaseView.extend({ 
    initialize: function(){ 
    //called manually from model using trigger 
    this.model.on('custom-handler', this.displayErrors, this); 
    } 
}); 
+0

原來,這是我自己的編程錯誤導致的問題。我有一個額外的模型,我使用的觀點是我必須堅持不同的路線,並且在調用清理之前,我並沒有解除綁定該模型的事件。我通過在子視圖中重寫cleanUp來解決該問題,解除綁定該額外模型的所有事件,然後調用BaseView.prototype.cleanUp.apply(this,arguments); 對不起,我不知道你能做到這一點 – Daniel 2013-03-19 22:07:21

回答

5

假設你是在骨幹網(0.9.10)的最新版本,您應該使用新的Backbone.Events.listenTo方法來綁定你的事件偵聽器。使用這種方法骨幹網將保留對對象的引用,並在view.remove()自動清除所有事件綁定:

this.listenTo(this.model, 'custom-handler', this.displayErrors); 

你做的所有事情在你的cleanUp方法(deleteundelegateEventsremoveDataunbind$el.html(''))看起來很像巫術編程。根本不需要這些步驟。

您的殭屍視圖很可能是由於您自己的代碼直接或間接引用了視圖。引用可以由事件處理函數,綁定函數,導出的閉包或任意數量的東西來保存。我建議您嘗試分析您的代碼,並使用Chrome開發人員工具'Heap profiler工具來嘗試查找保留的對象及其引用者。

檢出my answer in this SO question,其中我描述了一種簡單的方法來查找特定代碼路徑中的內存泄漏。雖然你的問題並不是直接涉及內存泄漏,但它是關於泄漏的引用,其保留的堆大小應該可以幫助你找到所持有的內容。

+0

我開始再次看到這個問題,我嘗試升級到Backbone 0.9.10從0.9.2開始,並使用您描述的listenTo方法。我的應用程序仍然表現出相同的行爲,所以問題必須存在於別處。 – Daniel 2013-03-19 21:51:26