Я всегда уничтожаю и создаю представления, потому что по мере того, как мое одностраничное приложение становится все больше и больше, хранение неиспользуемых живых представлений в памяти только для того, чтобы я мог их повторно использовать, становится все труднее поддерживать.
Вот упрощенныйверсия метода, который я использую для очистки моих представлений, чтобы избежать утечек памяти.
Сначала я создаю BaseView, от которого наследуются все мои представления.Основная идея заключается в том, что мой View будет сохранять ссылку на все события, на которые он подписан, так что, когда придет время утилизировать View, все эти привязки будут автоматически отменены.Вот пример реализации моего BaseView:
var BaseView = function (options) {
this.bindings = [];
Backbone.View.apply(this, [options]);
};
_.extend(BaseView.prototype, Backbone.View.prototype, {
bindTo: function (model, ev, callback) {
model.bind(ev, callback, this);
this.bindings.push({ model: model, ev: ev, callback: callback });
},
unbindFromAll: function () {
_.each(this.bindings, function (binding) {
binding.model.unbind(binding.ev, binding.callback);
});
this.bindings = [];
},
dispose: function () {
this.unbindFromAll(); // Will unbind all events this view has bound to
this.unbind(); // This will unbind all listeners to events from
// this view. This is probably not necessary
// because this view will be garbage collected.
this.remove(); // Uses the default Backbone.View.remove() method which
// removes this.el from the DOM and removes DOM events.
}
});
BaseView.extend = Backbone.View.extend;
Всякий раз, когда необходимо привязать View к событию модели или коллекции, я бы использовал метод bindTo.Например:
var SampleView = BaseView.extend({
initialize: function(){
this.bindTo(this.model, 'change', this.render);
this.bindTo(this.collection, 'reset', this.doSomething);
}
});
Всякий раз, когда я удаляю представление, я просто вызываю метод dispose, который автоматически очищает все:
var sampleView = new SampleView({model: some_model, collection: some_collection});
sampleView.dispose();
Я поделился этой техникой с людьми, которые пишутэлектронная книга "Backbone.js on Rails", и я считаю, что именно эту технику они приняли для этой книги.
Обновление: 2014-03-24
Начиная с версии 0.9.9, к событиям добавлены listenTo и stopListening с использованием тех же методов bindTo и unbindFromAll, которые показаны выше.Кроме того, View.remove автоматически вызывает stopListening, поэтому связывание и открепление теперь так же просто:
var SampleView = BaseView.extend({
initialize: function(){
this.listenTo(this.model, 'change', this.render);
}
});
var sampleView = new SampleView({model: some_model});
sampleView.remove();