每次创建视图并打开对话框时,我都会收到n
组事件,其中n
是对话框打开的次数。在下面的示例中,每次点击fooButton
,我都会点击n
按钮点击事件。我知道我应该取消绑定事件,但this.undelegateEvents()
无效。
根据我对SimpleDialog(和其他对话框小部件的工作方式)的理解,在创建对话框时,div的内容被复制到另一个元素中,这表明我应该能够捕获创建的元素(比如说{ {1}})然后在那上面调用undelegateEvents。这种方法也不起作用。
有什么想法吗?
$dialog = this.$el.modal();
感谢您的帮助!
切换到JQuery UI对话框解决了问题。请参阅下面的答案。
答案 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');
}
}
});