Avoid ghost views in you Backbone.js application
jules.boussekeyt.org
jules.boussekeyt.org
"Calling remove() on a Backbone.View does several things:
Remove Javascript events (click, keypress, blur, ...)
Unbind all events of the model (change, sync, remove)
Remove the element from the DOM"
But if you look at the code for Backbone.View.remove(): remove: function() {
this.$el.remove();
return this;
},
It removes the $el from the DOM. jQuery's function will automagically go ahead and remove any event listeners attached to $el or it's children. Zepto's remove() does not.But the most dangerous assumption the author made is that it will unbind events from the model. It does nothing of the sort - you need to manually override remove() in your views to detach any event listeners on models/collections/views/routers. If you don't do this, the views will still exist in memory, consider the following:
var Model = new Backbone.Model();
var View = new (Backbone.View.extend({
initialize: function () {
Model.on("change", this.render, this);
}
})();
View.remove();
console.log(Model._callbacks);
If you dig into the Model._callbacks object you'll eventually find the View instance, still referenced (and so still in memory). The simple way to fix this would be to add this remove function to the view: remove: function () {
Model.off(this);
return Backbone.View.prototype.remove.call(this);
}