1

我在我的一个观点中这样做:

render: function($options) {
    ...

    this.collection.on('reset', _(function() {
        this.render($options);
    }).bind(this));

    ....
}

问题是,只要reset触发了重新渲染,reset就会创建一个新的绑定,从而导致重新渲染的 2x、4x、8x 等次。

将绑定移动到初始化部分有点棘手(这应该可以解决这个问题),但是由于它不是一个选项,是否有任何其他可用的解决方案,比如让 Backbone 检查此事件之前是否已绑定,或者其他什么?

4

4 回答 4

2

将您的绑定移动到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);
    //...
}

这其实是同一个逻辑,只是穿了不同的衣服。您还可以使用显式标志和ifinrender或将函数分配给this._finishininitialize并且该函数将delete this._finish.

于 2012-09-13T04:48:47.257 回答
1

比如让 Backbone 检查这个事件之前是否已经绑定过,或者其他什么?

当然..

!!this.collection._events["render"]

Backbone 没有公开使其有用所需的大部分 API。没关系,随便用。

于 2015-03-17T03:22:40.697 回答
0

首先,将您的事件处理函数定义为命名函数

var self = this;
var onReset = function() {
    self.render($options);
}

然后,每次调用 render 时防御性地解除绑定函数

this.collection.off('reset', onReset);
this.collection.on('reset', onReset);
于 2012-09-13T04:31:44.687 回答
0

我最近使用 javascript 变量完成了这项工作。

在任何功能之外,我声明:

var boundalready =0

然后,在函数内部:

if (boundalready == 0){
      boundalready = 1;
      bind(this);
    };

这对我很有效。

于 2012-09-13T06:00:51.973 回答