我會盡量不喊,但是請別再試圖綁定意見現有元素。讓視圖創建並擁有自己的el
,然後在更換之前先致電view.remove()
將其關閉。這個簡單的改變解決了觀看事件中的許多問題,如果你不這樣做,你應該總是三思而後行(再多兩次)。
在你的情況,你就必須HTML這樣的:
<script id="t" type="text/x-underscore">
<div id="myView">
<button id="test_button">
Test Button
</button>
</div>
</script>
<div id="container">
</div>
<ul id="output"> <!-- This is outside the container because we're going to empty and refill it -->
</ul>
而JavaScript是這樣的:
var myView = Backbone.View.extend({
events: {
'click #test_button': 'buttonClicked'
},
render: function() {
this.$el.html($('#t').html());
return this;
},
buttonClicked: function() {
$("#output").append('<li>Button was clicked</li>');
}
});
$(document).ready(function(){
var v = new myView();
$('#container').append(v.render().el);
v.remove(); // <----------------- Clean things up before adding a new one
v = new myView();
$('#container').append(v.render().el);
});
問題的興趣:
- 創建然後渲染它然後把它放在頁面上。
- 當你完成它時,請在視圖上調用
remove
。
- 視圖進入容器內部。來電者擁有容器,該視圖擁有其
el
。
- 有任何地方沒有
delegateEvents
或undelegateEvents
調用。那些存在的問題幾乎總是指向您的應用程序IMO中的結構問題。
- 每個視圖都是自包含的:外部世界不會與視圖內的任何東西一起玩,並且視圖會將自己的手保持在自己的手中。
更新小提琴:https://jsfiddle.net/bp8fqdgm/
但是,爲什麼不是你嘗試undelegateEvents
做什麼? undelegateEvents
looks like this:
undelegateEvents: function() {
if (this.$el) this.$el.off('.delegateEvents' + this.cid);
return this;
},
的cid
是按次例如唯一的,這樣每個視圖實例都使用自己獨特的命名空間爲delegateEvents
結合事件。這意味着,這樣的:
this.undelegateEvents();
this.delegateEvents();
是說:
- 刪除該視圖的此實例已綁定的事件。這些活動將在該
'.delegateEvents' + this.cid
命名空間,其中cid
是每個視圖實例是唯一被發現。
- 綁定事件視圖定義(或在
delegateEvents
呼叫的事件)的此實例。這些事件將使用'.delegateEvents' + this.cid
命名空間進行附加。
所以你undelegateEvents
呼叫被刪除事件,但不是所有的人,只有特定的事件綁定被刪除該視圖實例補充道。
你this.undelegateEvents()
調用實際上並沒有完成任何事情,因爲它是在錯誤的地點和錯誤的時間調用。如果new View
來電者做了undelegateEvents
電話:
var v = new myView({el: "#myView"});
v.undelegateEvents();
new myView({el: "#myView"});
然後它會發生在正確的地方,並在合適的時間。當然這意味着你的路由器需要跟蹤當前的視圖,以便它能在合適的時間currentView.undelegateEvents()
;但如果你這樣做,那麼你會更好(IMO)採取我在答案頂部概述的方法。
我不明白你正在嘗試通過初始化視圖做兩次。如果你想在行動中看到undelegateEvents,裏面buttonClicked追加後,將它和實例化視圖一次 - 點擊僅會被解僱,那麼事件綁定被刪除。 – bdc
@bdc - 我有一個Backbone應用程序,我正在開發它通過在Backbone路線中實例化它們來切換視圖,但是這會導致在任何特定視圖中委派的事件多次觸發,具體取決於該視圖的路由實例化視圖的次數(即,由用戶在視圖之間來回導航而不重新加載頁面)。我想我可以解決這個問題,只需在重新授權視圖之前刪除視圖的任何委託事件。另外,我想知道爲什麼我的例子做它的作用 - 我會認爲undelegateEvents會做到這一點。 – Bill
在切換路由之前調用undelegateEvents,而不是initialize()應該爲你工作。它在initialize內部不起作用的原因是因爲您正在實例化視圖的兩個單獨實例。第二種情況不受一審事件的約束。骨幹來源:this。$ el.off('。delegateEvents'+ this.cid)。即使DOM元素相同,this.cid對於您實例化的每個視圖都是唯一的。 – bdc