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

Jim*_*hao 11 javascript jquery backbone.js

我有一些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();
Run Code Online (Sandbox Code Playgroud)

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

任何人都知道为什么unbind不工作?

sle*_*led 37

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

$(this.el).delegate('.button', 'click', yourCallback);
Run Code Online (Sandbox Code Playgroud)

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

你必须像这样取消事件:

$(this.el).undelegate('.button', 'click');
Run Code Online (Sandbox Code Playgroud)

(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();
Run Code Online (Sandbox Code Playgroud)

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

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


bra*_*ing 17

你可以用另一种方式解决

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();
Run Code Online (Sandbox Code Playgroud)

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


Gar*_*ett 7

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

this.undelegateEvents();
Run Code Online (Sandbox Code Playgroud)