В принципе, то, что вы делаете, должно работать, но есть некоторые вещи, которые Backbone не может исправить, потому что он о них не знает.
Во-первых, вы должны убедиться, что используете последнюю версию Backbone (0.9.9
или новее). Были внесены некоторые улучшения в код привязки событий, что упрощает методу View.remove
выполнение всей необходимой очистки.
Общие ошибки:
Прослушивание событий модели:
//don't use other.on (Backbone doesn't know how to clean up)
this.model.on('event', this.method);
//use this.listenTo (Backbone cleans up events when View.remove is called)
//requires Backbone 0.9.9
this.listenTo(this.model, 'event', this.method);
Прослушивание событий DOM за пределами вашего представления:
//if you listen to events for nodes that are outside View.el
$(document).on('event', this.method);
//you have to clean them up. A good way is to override the View.remove method
remove: function() {
$(document).off('event', this.method);
Backbone.View.prototype.remove.call(this);
}
Прямые ссылки:
//you may hold a direct reference to the view:
this.childView = otherView;
//or one of its methods
this.callback = otherView.render;
//or as a captured function scope variable:
this.on('event', function() {
otherView.render();
});
Закрытия:
//if you create a closure over your view, or any method of your view,
//someone else may still hold a reference to your view:
method: function(arg) {
var self = this;
return function() {
self.something(x);
}
}
Избегание следующих ловушек должно помочь вашим представлениям правильно очиститься.
Изменить на основе комментария:
Ах, вы не упомянули всю проблему в своем вопросе. Насколько я понимаю, проблема с вашим подходом заключается в том, что вы пытаетесь отобразить два представления в один и тот же элемент:
var View1 = Backbone.View.extend({el:"#container" });
var View2 = Backbone.View.extend({el:"#container" });
И когда вы удаляете View1
, View2
отображается неправильно.
Вместо того, чтобы указывать представление el
, вы должны отображать представления в элемент. На вашей странице вы должны иметь элемент #container
и добавить элемент представления в контейнер.
loadPostLeads: function () {
var self = this;
require(['views/post-leads'], function (leads) {
self.renderView(new leads());
})
},
loadDashboard: function () {
var self = this;
require(['views/dashboard'], function (dashboard) {
self.renderView(new dashboard());
})
},
renderView: function(view) {
if(window.currentView) {
window.currentView.remove();
}
//the view itself does not specify el, so you need to append the view into the DOM
view.render();
$("#container").html(view.el);
window.currentView = view;
}
person
jevakallio
schedule
14.03.2013