11

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?

Steve Robillard
  • 13,445
  • 3
  • 36
  • 32
Preslav Rachev
  • 3,983
  • 6
  • 39
  • 63
  • related? http://stackoverflow.com/questions/10429648/backbone-js-how-to-unbind-from-events-on-model-remove/10433015#10433015 – fguillen May 24 '12 at 13:05
  • Are you re-using an `el` when switching views rather than creating new ones? The jQuery `delegate` is bound to the view's `el`. – mu is too short May 24 '12 at 16:13
  • @muistooshort yes, I oftentimes reuse the same DOM container, and give it to the view, instead of creating and attaching a new one every so often. That's why removing the ghost callbacks is of critical importance – Preslav Rachev May 25 '12 at 06:32
  • Then calling `undelegateEvents` during cleanup is to be expected and fine. `remove` doesn't `undelegateEvents` because it kills off the whole `el` and there'd be no point. – mu is too short May 25 '12 at 06:42
  • If you have a custom `remove()` method, please post it in your question. – JMM May 25 '12 at 18:24

1 Answers1

6

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().

Community
  • 1
  • 1
JMM
  • 26,019
  • 3
  • 50
  • 55