我应该如何在打开SimpleModal对话框的BackBone.js视图中取消绑定事件?

时间:2012-12-23 21:10:41

标签: javascript backbone.js simplemodal

每次创建视图并打开对话框时,我都会收到n组事件,其中n是对话框打开的次数。在下面的示例中,每次点击fooButton,我都会点击n按钮点击事件。我知道我应该取消绑定事件,但this.undelegateEvents()无效。

根据我对SimpleDialog(和其他对话框小部件的工作方式)的理解,在创建对话框时,div的内容被复制到另一个元素中,这表明我应该能够捕获创建的元素(比如说{ {1}})然后在那上面调用undelegateEvents。这种方法也不起作用。

有什么想法吗?

$dialog = this.$el.modal();

感谢您的帮助!

切换到JQuery UI对话框解决了问题。请参阅下面的答案。

6 个答案:

答案 0 :(得分:3)

每次实例化视图时,Backbone都会在el上致电delegateEvents

  

delegateEvents delegateEvents([events])

     

[...]默认情况下,在View的构造函数中为您调用 delegateEvents ,[...]

所以每次你这样做:

new MyDialogView({el: $("#dialog") });

您将jQuery delegate附加到#dialog。您的问题是您没有自行清理,您应该在关闭对话框时删除delegate

关闭对话框时应该致电undelegateEvents

fooPressed: function() {
    alert("clicked");
    this.undelegateEvents();
    $.modal.close();
}

或者,你可以创建一次视图,并调用一些方法根据需要弹出它。完成设置后,您只需停用render来自initialize的所有new MyDialogView(...),然后将视图保存在变量中,然后根据需要保存my_dialog_view.render()。< / p>

答案 1 :(得分:1)

您使用的是什么版本的Backbone?截至0.9.9:

  

最重要的是,Backbone事件有两个新方法:listenTo和stopListening。这些是通常打开和关闭的反转控件的味道,并且使得清理对象在其他对象上侦听的所有事件变得更容易一些。使用view.remove()销毁视图时,现在将自动完成。请注意,关于使用垃圾收集语言进行编程的常规规则仍然适用。

我猜你每次打开你的模态时,你的关闭按钮应该调用view.remove()。从最新版本开始,Backbone现在应该从视图中解除所有事件的绑定,而不必手动完成。

MyDialogView = Backbone.View.extend({
    initialize: function(options){
        this.render();
    },
    render: function() {

        this.$el.empty().append("<button id='fooButton'>Foo</button>");

        this.$el.modal({ "static": true });
    },
    events: {
        "click #fooButton": "fooPressed",
        "click #close": "closeView"
    },
    closeView: {
      this.remove();
      $.modal.close();
    },
    fooPressed: function() {
        alert("clicked");
    }
});

答案 2 :(得分:0)

如何使用jQuery的off方法?

unbindEvents : function(){
    this.$el.off();
}

答案 3 :(得分:0)

如果您每次点击MyDialogView时都不会创建'#openDialog'的新实例,但只渲染现有的实例,该怎么办?

MyDialogView = Backbone.View.extend({
    initialize: function(options){
        //this.render(); // don't need to call it here
    }
    // ...
});

$(function(){
    var myDialogView = new MyDialogView({
        el: $("#dialog")[0]
    });
    $("#openDialog").click(function() {
        myDialogView.render();
    });
});

答案 4 :(得分:0)

我的同事Anton找到了一个解决方案,将Simple Modal替换为JQuery UI Dialog,因为它返回一个可以安全地分配给它的元素。$ el(简单模态不能)。在开放时:

that.$el = $(that.$el.dialog({
    modal: true,
    resizable: false,
    "beforeClose": function (dialog) {
        that.stopListening();
        that.undelegateEvents();
    }
}));

再次感谢所有试图提供帮助的人,希望这有助于将来。

答案 5 :(得分:0)

通过在错误的范围内使用this来解决该问题,因此在这种情况下,this被引用到方法而不是视图实例。 以下是我之前删除视图事件的方法,并且效果很好。

var JobContainerNumberView = Backbone.View.extend({
events: {
        "focusout input.txtNumber": "checkBookingExists"
    },
    checkBookingExists: function() {
        var _this = this;
        var this_input = _this.$('input.txtNumber'); // text box where container is
        var booking_number = this_input.val();
        if ( booking_number != '') {
            $.post('booking/booking_exists', {'booking_number': booking_number},
                function(data,status,xhr) {
                if (data.exists) {
                    alert(data.message);
                    // stop only focusout event for the input
                    $(_this.el).off('focusout', 'input.txtNumber');
                    //remove all events on view
                    //_this.undelegateEvents();
                }
            },'json');
        }
    }

});