2012-06-26 95 views
4

我正在嘗試與骨幹js建立一個交換視圖,發現我的綁定事件多次觸發,當我切換視圖幾次。Backbone綁定事件多次觸發

下面是爲了更好地說明代碼:

HTML

<div id='container'> 
    halo world 
</div> 

<button id='but1'>red view</button> 
<button id='but2'>blue view</button> 

CSS

#red_view{ 
    width:400px; 
    height:400px; 
    background-color:red;   
} 
#blue_view{ 
    width:400px; 
    height:400px; 
    background-color:blue;   
} 
.button,.button2{ 
    width:300px; 
    height:300px; 
    background-color:gray; 
} 

的JavaScript

RedView = Backbone.View.extend({ 
    el: "#container", 
    events:{"click .button":"clickme"}, 
    clickme:function(){ 
     alert('redview');       
    }, 
    initialize: function(){ 
     this.$el.html("<div id='red_view'><div class='button'>Click Me</div></div>");    
    } 
}); 

BlueView = Backbone.View.extend({ 
    el: "#container", 
    events:{"click .button2":"clickme2"}, 
    clickme2:function(){ 
     alert('blueview');       
    },  
    initialize: function(){ 
     this.$el.html("<div id='blue_view'><div class='button2'>Click Me</div></div>");    
    } 
}); 

$(document).ready(function(){ 
    //var router = new SystemRouter(); 

    $('#but1').click(function(){ 
     var view = new RedView(); 
    }); 
    $('#but2').click(function(){ 
     var view = new BlueView(); 
    });  
}); 

如果您單擊紅色視圖3次,然後按'點我'。它也會彈出三次警報。我懷疑有必要在某個地方解除事件,但找不到合適的方法來做到這一點。最好提供一些正確執行此操作的參考。

下面是jsfiddle演示的鏈接。 http://jsfiddle.net/mochatony/DwRRk/31/

+1

你並沒有清理你的意見,留下你的鬼影。在下面檢查我的答案! – jakee

回答

11

每次點擊red viewblue view -buttons您創建一個新的紅色或藍色查看每一次。您將它們的事件哈希綁定爲響應點擊源自類buttonbutton2的按鈕的DOM事件。

  1. 按 '紅視' 的3倍 - RedView> 3個實例創建
  2. 帶班的 '按鈕',單擊按鈕 - > DOM事件的RedView聽
  3. 3個實例說DOM事件 - > 3個警報

這是因爲在創建新的視圖之前,您並沒有清理視圖,因此,即使無法看到它們,仍然會出現響應事件的鬼影視圖。 (More info on the events hash)你可以用這樣的東西來清理你的視圖中的事件。

cleanup: function() { 
    this.undelegateEvents(); 
    $(this.el).clear(); 
} 

這裏是工作的意見http://jsfiddle.net/DwRRk/34/

對良好做法的提示清理你的提琴:你應該使用類似渲染方法的東西附加到DOM,使用初始化只是初始化爲您的視圖提供所需的值。

1

每次單擊按鈕時都會創建一個新視圖,而不會破壞前一個按鈕。嘗試使用一個單一的視圖喜歡這樣的:

http://jsfiddle.net/DwRRk/32/

var SomeModel = Backbone.Model.extend({}); 

var SomeView = Backbone.View.extend({ 
    el: "#container", 
    model: SomeModel, 
    events: { 
     "click .button": "clickme" 
    }, 
    clickme: function() { 
     alert(this.model.get("color")); 
    }, 
    colorChanged: function() { 
     this.$el.html("<div id='" + this.model.get("color") + "_view'><div class='button'>Click Me</div></div>"); 
    }, 

    initialize: function() { 
     _.bindAll(this, "colorChanged"); 
     this.model.on("change:color", this.colorChanged); 
     this.model.on("reset", this.colorChanged); 
    } 
}); 



$(document).ready(function() { 
    //var router = new SystemRouter(); 
    var model = new SomeModel({color: "red"}), 
     view = new SomeView({model: model}) 


    $('#but1').click(function() { 
     model.set("color", "red"); 
    }); 
    $('#but2').click(function() { 
     model.set("color", "blue"); 
    }); 
});​ 
+0

謝謝。這爲我提供了一個新的想法,如何以不同的方式實現它,但對於我的情況,我有一個非常不同的觀點,我將基於路由實例化它。所以,我很好奇如何實現這一點。 – TonyTakeshi

+0

@TonyMocha你可以改變他們隱藏/顯示的狀態取決於什麼路由? – Esailija

1

這裏的刪除鬼觀點的另一種方法(我使用的是什麼)

disposeView: function(view){ 
    Backbone.View.prototype.close = function() { 
     this.unbind(); 
     this.undelegateEvents(); 
    }; 

    /* --Destroy current view */ 
    if(this.currentView !== undefined) { 
     this.currentView.close(); 
    } 

    /* --Create new view */ 
    this.currentView = view; 
    this.currentView.delegateEvents(); 

    return this.currentView; 
} 

disposeView(new view()); 

一定要始終返回在你看來,否則這是不行的「本」。

+0

這是超級光滑的。這是最簡單的解決方案。我在Backbone Zombie的視圖中遇到了很多麻煩,直到這個問題才得以解決。謝謝! –