We have some legacy non-backbone code in our web application. Although we attach views to existing DOM elements there is still some yet-to-be-refactored code that deletes certain DOM elements i.e. the delete call doesn’t go through the view but is more like a jQuery call $('#domID').remove();
I have a nagging feeling that the backbone view probably hangs around as a zombie, but I don’t have a way to see it? Is this harmful? Should we make it priority to refactor and have all the deletes go via the view and call view.remove() and view.unbind() for proper deletion?
Would the view be garbage collected if the DOM node is deleted independently? I guess if not if it’s bound to some event, but what if it isn’t?
The view will only linger on if there is a reference to it somewhere. There are four sources of stray references to consider:
this.collection.on('reset', this.render)and such.events.$(...).on(...)calls.this.current_view = new V(...).(1) is normally handled by the view’s
removemethod and you have to callremoveyourself, there’s nothing in Backbone or jQuery that can do this for you. For example: http://jsfiddle.net/ambiguous/e574Z/(2) is easy. Backbone views use a single
delegatecall to bind the view’s events to the view’sel. So, if you remove the view’selthrough a simple$(x).remove()then the event reference goes away. However, if you’re attaching different views to the sameel, you’ll need to callundelegateEventsto detach thedelegate; this would normally be done in aremovemethod:but, again, you have to call
removeyourself somewhere.(3) is rare but sometimes necessary in the case of window scroll events, body click events for dialogs, and things like that. Of course, you have to clean these up yourself as Backbone can’t know what you’re doing behind its back and the elements that you’re binding to would be outside of the view’s
el(or you’d be in (2)). Where would you clean these up? Theremovemethod of course.(4) is, as always, up to you. Usually, this sort of thing is handled like this:
Yes, there’s
removeagain.So, if all you have are things like (2), then
$('#domID').remove();will be fine and shouldn’t leave any zombies; in fact, the defaultremoveimplementation is justthis.$el.remove()and the documentation says as much:However, you probably have some things like (1) involved as well so adding/updating all your
removemethods and callingview.remove()to remove views would be a good idea.