Search code examples
eventsbackbone.js

Backbone: Attaching event to this.$el and re rendering causes multiple events to be bound


I need to attach an event to the main view element, this.$el. In this case its an 'LI'. Then I need to re render this view sometimes. The problem is if i re render it, it attaches any events in the onRender method that is attached to this.$el each time its rendered. So if i call this.render() 3 times the handler gets attached 3 times. However, if i attach the event to a childNode of this.$el, this does not happen and the events seem to be automatically undelegated and added back on each render. The problem is I NEED to use the main this.$el element in this case.

Is this a bug? Shouldn't this.$el function like the childNodes? Should I not be attaching things to this.$el?

inside the view:

onRender: function(){
    this.$el.on('click', function(){
    // do something
});

Solution

  • If you're able to use the view's event hash, you could do the following:

    var Bookmark = Backbone.View.extend({
        events: {
            'click': function() {
                console.log('bound once')
            }
        }
        ...});
    

    If for some reason that's not an option, you could explicitly remove any existing event listeners for this event in the render method, which will prevent the listener from being attached multiple times:

    var Bookmark = Backbone.View.extend({
        ...
        render: function(x) {
            this.$el.off('click.render-click');
            this.$el.html(this.template());
            this.$el.on('click.render-click', function () { 
                console.log('only ever bound once');
            });
            return this;
        }
    });