2013-03-14 138 views
0

所以我有我的骨幹應用程序殭屍視圖相同的着名問題。我試圖成爲一個超級英雄:P失敗的方法來擺脫殭屍的殭屍視圖

var Router=Backbone.Router.extend({ 
      routes:{ 
        "":"loadDashboard", 
        "home":"loadDashboard", 
        'post-leads':"loadPostLeads" 
       }, 
       initialize:function(){ 
       window.currentView=null; 
       }, 

      loadPostLeads:function(){ 
      require(['views/post-leads'],function(leads){ 
      if(window.currentView!=null) 
      {window.currentView.remove();} 
      window.currentView=new leads(); 
      window.currentView.render(); 
      }) 

     }, 

       loadDashboard: function(){ 
     require(['views/dashboard'],function(dashboard){ 
      if(window.currentView!=null) 
      {window.currentView.remove();} 
      window.currentView=new dashboard(); 
      window.currentView.render(); 
      }) 
     } 
      }); 

這是行不通的。我想要一些簡單而不想使用木偶或類似的東西。上面出了什麼問題?這是一個明智的做法嗎?

+0

I LOLed @superhero:D – 2013-03-14 06:18:07

+0

:)這種方法的任何字? – beNerd 2013-03-14 06:56:42

回答

3

原則上你應該做的工作,但有一些事情,骨幹無法清理,因爲它不知道他們。

首先,您應該確保您使用的是最新版本的Backbone(0.9.9或更新版本)。對事件綁定代碼進行了一些改進,這使得View.remove方法可以更輕鬆地進行所有必要的清理。

的常見的問題有:

聽模型事件

//don't use other.on (Backbone doesn't know how to clean up) 
this.model.on('event', this.method); 

//use this.listenTo (Backbone cleans up events when View.remove is called) 
//requires Backbone 0.9.9 
this.listenTo(this.model, 'event', this.method); 

監聽DOM事件視圖的範圍之外:

//if you listen to events for nodes that are outside View.el 
$(document).on('event', this.method); 

//you have to clean them up. A good way is to override the View.remove method 
remove: function() { 
    $(document).off('event', this.method); 
    Backbone.View.prototype.remove.call(this); 
} 

直接引用

//you may hold a direct reference to the view: 
this.childView = otherView; 

//or one of its methods 
this.callback = otherView.render; 

//or as a captured function scope variable: 
this.on('event', function() { 
    otherView.render(); 
}); 

瓶蓋

//if you create a closure over your view, or any method of your view, 
//someone else may still hold a reference to your view: 
method: function(arg) { 
    var self = this; 
    return function() { 
    self.something(x); 
    } 
} 

避免以下誤區應該幫助你的觀點得到正確清理。

編輯基於評論

啊,你沒有提到你的問題的全部問題。你的方法的問題是,因爲我推測,是你想呈現兩種觀點同一元件:

var View1 = Backbone.View.extend({el:"#container" }); 
var View2 = Backbone.View.extend({el:"#container" }); 

而當你刪除View1,在View2不能正確渲染。

而不是指定視圖el,您應該將視圖呈現爲一個元素。在您的頁面上,您應該有一個#container元素,並將該視圖的元素附加到容器中。

loadPostLeads: function() { 
    var self = this; 
    require(['views/post-leads'], function (leads) { 
    self.renderView(new leads()); 
    }) 
}, 

loadDashboard: function() { 
    var self = this; 
    require(['views/dashboard'], function (dashboard) { 
    self.renderView(new dashboard()); 
    }) 
}, 

renderView: function(view) { 
    if(window.currentView) { 
    window.currentView.remove(); 
    } 

    //the view itself does not specify el, so you need to append the view into the DOM 
    view.render(); 
    $("#container").html(view.el); 

    window.currentView = view; 
} 
+0

看到,當我執行我的代碼時,它將其刪除。但是當我創建一個新的視圖,並做console.log(window.currentView)它顯示埃爾undefined :( – beNerd 2013-03-14 09:22:00

+0

@beNerd,編輯我的答案,你真的應該嘗試給你的原始問題的所有信息 – jevakallio 2013-03-14 10:06:23

+1

你可能想要'return Backbone.View.prototype.remove.call(this);'在你的'remove'中匹配默認行爲。 – 2013-03-14 19:18:41