我有一个视图(我将调用父视图),其中包含另一个视图(子视图)。父视图具有使用“上下文菜单”事件的元素(右键单击时,会显示一组菜单选项)。当用户从菜单中选择一个项目时,它会触发回调。从那里,我在子视图中触发一个事件。这是我的触发器:
that.trigger("editFileFolder", {fileType: fileType});
在我的子视图的初始化函数中,我有这个:
this.listenToOnce(this.options.parent,'editFileFolder', this.editFileObjectEvent);
editFileObjectEvent函数调用另一个要创建的视图(包含某些字段的对话框,取消按钮和保存按钮)。如果用户点击取消,一切正常。如果用户单击“保存”按钮,则视图将执行ajax调用,保存到服务器并关闭对话框。但是,下次用户右键单击并选择相同的菜单项时,editFileObjectEvent将被调用两次(导致对话框被添加到父视图两次)。
任何人都可以解释为什么它被调用两次以及如何解决这个问题?如果您想查看特定代码,请告诉我,我可以添加它。有很多,所以我不想压倒这个问题。
感谢
答案 0 :(得分:2)
我认为调用this.listenToOnce
的函数被调用两次。你应该尽量避免这种情况。但是,如果这不可能,您可以通过在绑定之前解除绑定来确保侦听器只绑定一次:
this.stopListening(this.options.parent, 'editFileFolder', this.editFileObjectEvent);
this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent);
或者你可以在你的实例上有一个属性来防止绑定两次:
if (!this.__boundListener) {
this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent);
this._boundListener = true;
}
所有侦听器都在this._listeningTo
中注册,您可以通过搜索来检查事件是否已被绑定。
您还可以重构代码:
MyModel.extend({
initialize: function() {
this.bindListenToOnce = _.once(this.bindListenToOnce);
},
abc: function() {
// do stuff
this.bindListenToOnce();
// do stuff
},
bindListenToOnce: function() {
this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent);
}
});