简体   繁体   中英

Backbone - Anyway to check if an event has been bound before?

I'm doing this inside one of my Views:

render: function($options) {
    ...

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

    ....
}

The problem is, whenever reset as well as the re-rendering has been triggered, a new reset binding will be created, resulting 2x, 4x, 8x, etc. times of re-rendering as it goes on.

It's a bit tricky to move the binding into the initialize section (which should solve this issue), however since it's not an option, is there any other solution available, like having Backbone checking if this event has been bound before, or something?

Moving your binding to initialize would be best but assuming that you have good reasons not to, you could just set a flag:

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);
    //...
}

There are lots of different ways to implement the flag, _.once just nicely hides the flag checking. You could also trigger an event in render have a listener that unbinds itself:

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);
    //...
}

That's the same logic really, just dressed up in different clothes. You could also use an explicit flag and an if in render or assign a function to this._finish in initialize and that function would delete this._finish .

like having Backbone checking if this event has been bound before, or something?

Sure..

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

Backbone doesn't expose most of the API required to make it useful. That's alright, use it anyway.

First, define your event handler function as a named function

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

Then, defensively unbind the function each time render is called

this.collection.off('reset', onReset);
this.collection.on('reset', onReset);

I recently accomplished this using a javascript variable.

Outside of any functions, I declared:

var boundalready =0

Then, inside the function:

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

This worked for me pretty well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM