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(){ ........ },