【问题标题】: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);
              };
          

          这对我很有效。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-01-14
            • 1970-01-01
            • 2011-04-17
            • 1970-01-01
            • 2011-09-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多