【问题标题】:Backbone - Anyway to check if an event has been bound before?Backbone - 无论如何要检查一个事件之前是否已经绑定过?
【发布时间】:2015-03-17 11:22:40
【问题描述】:
我正在我的一个视图中执行此操作:
render: function($options) {
...
this.collection.on('reset', _(function() {
this.render($options);
}).bind(this));
....
}
问题是,每当触发reset 以及重新渲染时,都会创建一个新的reset 绑定,从而导致重新渲染2x、4x、8x 等次.
将绑定移动到初始化部分有点棘手(这应该可以解决这个问题),但是由于它不是一个选项,是否有任何其他可用的解决方案,例如让 Backbone 检查此事件之前是否已绑定,或者什么?
【问题讨论】:
标签:
javascript
backbone.js
【解决方案1】:
将绑定移动到initialize 是最好的,但假设你有充分的理由不这样做,你可以设置一个标志:
initialize: function() {
var _this = this;
this._finish_initializing = _.once(function($options) {
_this.collection.on('reset', function() {
_this.render($options);
});
});
//...
},
render: function($options) {
this._finish_initializing($options);
//...
}
有很多不同的方式来实现标志,_.once 只是很好地隐藏了标志检查。你也可以在render 触发一个事件,有一个解绑自己的监听器:
initialize: function() {
var finish_initializing = function($options) {
/* your binding goes here ... */
this.off('render', finish_initializing);
};
this.on('render', finish_initializing, this);
},
render: function($options) {
this.trigger('render', $options);
//...
}
这其实是同一个逻辑,只是穿了不同的衣服。您还可以在render 中使用显式标志和if,或者在initialize 中为this._finish 分配一个函数,该函数将为delete this._finish。
【解决方案2】:
比如让 Backbone 检查这个事件之前是否已经绑定过,或者其他什么?
当然..
!!this.collection._events["render"]
Backbone 并未公开使其有用所需的大部分 API。没关系,随便用吧。
【解决方案3】:
首先,将您的事件处理函数定义为命名函数
var self = this;
var onReset = function() {
self.render($options);
}
然后,每次调用 render 时防御性地解除绑定函数
this.collection.off('reset', onReset);
this.collection.on('reset', onReset);
【解决方案4】:
我最近使用 javascript 变量完成了这项工作。
在任何函数之外,我声明:
var boundalready =0
然后,在函数内部:
if (boundalready == 0){
boundalready = 1;
bind(this);
};
这对我很有效。