Backbone.js View无法正确取消绑定事件

我有一些Backbone.js代码将click事件绑定到一个按钮,我想点击后取消绑定,代码示例如下:

var AppView = Backbone.View.extend({ el:$("#app-view"), initialize:function(){ _.bindAll(this,"cancel"); }, events:{ "click .button":"cancel" }, cancel:function(){ console.log("do something..."); this.$(".button").unbind("click"); } }); var view = new AppView(); 

然而unbind不起作用,我尝试了几种不同的方式,并在jQuery初始化函数中结束事件,但在Backbone.events模型中没有。

有谁知道为什么unbind不工作?

它不起作用的原因是Backbonejs没有绑定DOM Element .button本身的事件。 它委托这样的事件:

 $(this.el).delegate('.button', 'click', yourCallback); 

(docs: http : //api.jquery.com/delegate )

你必须像这样取消事件:

 $(this.el).undelegate('.button', 'click'); 

(docs: http : //api.jquery.com/undelegate )

所以你的代码应该是这样的:

 var AppView = Backbone.View.extend({ el:$("#app-view"), initialize:function(){ _.bindAll(this,"cancel"); }, events:{ "click .button":"cancel" }, cancel:function(){ console.log("do something..."); $(this.el).undelegate('.button', 'click'); } }); var view = new AppView(); 

解决此问题的另一种方法(更好)是现在每次调用cancel函数时创建一个像this.isCancelable这样的状态属性,检查this.isCancelable是否设置为true,如果是,则继续执行操作并将this.isCancelable设置为false 。

另一个按钮可以通过将this.isCancelable设置为true来重新激活取消按钮,而不绑定/解除对click事件的绑定。

你可以用另一种方式解决

 var AppView = Backbone.View.extend({ el:$("#app-view"), initialize:function(){ _.bindAll(this,"cancel"); }, events:{ "click .button":"do" }, do:_.once(function(){ console.log("do something..."); }) }); var view = new AppView(); 

underscore.js一旦函数确保包装函数只能被调用一次。

假设您要取消所有事件的取消操作,有一种更简单的方法:

 this.undelegateEvents(); 

我喜欢bradgonesurfing的答案。 但是,当创建View的多个实例时,我遇到了使用_.once方法的问题。 也就是说_.once会限制只为该类型的所有对象调用一次的函数,即限制是在类级别而不是实例级别。

我这样处理问题:

 App.Views.MyListItem = Backbone.View.extend({ events: { 'click a.delete' : 'onDelete' }, initialize: function() { _.bindAll(this); this.deleteMe = _.once(this.triggerDelete); }, // can only be called once triggerDelete: function() { console.log("triggerDelete"); // do stuff }, onDelete:(function (e) { e.preventDefault(); this.deleteMe(); }) }); 

希望这会对某人有所帮助

你可以简单地使用object.off ,下面的代码对我有用

 initialize:function () { _.bindAll(this, 'render', 'mouseover', 'mouseout', 'delete', 'dropout' , 'unbind_mouseover', 'bind_mouseover'); ....... }, events: { 'mouseover': 'mouseover', 'unbind_mouseover': 'unbind_mouseover', 'bind_mouseover': 'bind_mouseover', ..... }, mouseover: function(){ $(this.el).addClass('hover'); this.$('.popout').show(); }, unbind_mouseover: function(){ console.log('unbind_mouseover'); $(this.el).off('mouseover'); }, bind_mouseover: function(){ ........ },