Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The best way to undelegate events once a view is no longer needed

Is it a bad practice to call undelegateEvents() in the view remove() method? Why wasn't it included by default by the backbone guys?

I realized I am falling into so many binding issues, when simply reinitializing a view variable. Although undelegateEvents() is being called automatically when a new view is created, it is trying to undelegate events for the newly instantiated view, not the previous one. Therefore, unless manually calling it every time, ghost event callbacks remain alive and screw up my apps.

What's the best way to handle this?

like image 752
Preslav Rachev Avatar asked May 24 '12 08:05

Preslav Rachev


1 Answers

Is it a bad practice to call undelegateEvents() in the view remove() method?

It's not necessary unless you're implementing your own remove() and you don't call Backbone.View.remove() or this.$el.remove(). That's if you're using jQuery, at least. Calling remove() on a Backbone view will call jQuery.remove() which will remove all of the DOM event listeners anyway.

I realized I am falling into so many binding issues, when simply reinitializing a view variable.

A lot of people seem to use Backbone.Events like it's some kind of magic that they don't need to clean up after, e.g.:

var View = Backbone.View.extend( {

  initialize : function ( options ) {

    // `on()` or `bind()`

    this.model.on( 'something', this.render, this );

  }

} );

See my answer on Delegating events to a parent view in Backbone

Is it possible that the ghost event issues you're experiencing are with Backbone events and not DOM events?

If you keep the model object around but want to get rid of that view object or its Backbone event registrations, you have to do view.model.off( null, null, this );. You have to unbind the events that you've registered on any external objects. If you want, you could override Backbone.View.remove() and do it there, but by default that method is just shorthand for view.$el.remove().

like image 199
JMM Avatar answered Sep 27 '22 17:09

JMM