我有一个Homeview,其中包含一些页面上的子视图,当我使用路由器导航到另一个页面时,如何清理现有视图,并为我要导航到的页面构建新视图?
此应用程序没有模型/集合,只有视图。
谢谢!
部分代码:
Home = Backbone.View.extend({
template: "static/js/templates/home.html",
initialize: function() {
_.bindAll(this);
this.render();
},
render: function() {
var view = this;
// Fetch the template, render it to the View element and call done.
namespace.fetchTemplate(this.template, function(tmpl) {
view.el.innerHTML=tmpl();
view.subRender();
});
return this;
},
subRender: function() {
var view = this;
var videoView = new Subview1({
el: $('#wrapper1'),
homeView: view
});
var timeView = new Subview2({
el: $("#wrapper2")
});
}
});
答案 0 :(得分:9)
如果你愿意,你可以使用骨干的事件机制来做这件事。
您只需要创建一个全局事件路由器,然后让每个视图都监听CloseView
事件。然后,您只需在收到CloseView
事件时执行所有关闭操作。
var dispatcher = _.clone(Backbone.Events)
Home = Backbone.View.extend({
...
initialize: function() {
...
dispatcher.on( 'CloseView', this.close, this );
}
close: function() {
// Unregister for event to stop memory leak
dispatcher.off( 'CloseView', this.close, this );
this.remove();
this.unbind();
this.views = []; // Clear the view array
}
...
});
SubView = Backbone.View.extend({
...
initialize: function() {
...
dispatcher.on( 'CloseView', this.close, this );
}
close: function() {
// Unregister for event to stop memory leak
dispatcher.off( 'CloseView', this.close, this );
// Do other close stuff here.
}
});
然后只是在路由器/其他地方调用dispatcher.trigger( 'OnClose' )
来触发关闭函数。
作为一种快捷方式,假设您想在每个导航上执行此关闭,您可以在路由器上注册事件(这里是自定义'OnClose'事件,或者只是获取每个导航的'all'事件)虽然你必须要小心,按照你期望的顺序调用事件。
也许有可能将这些代码重构为Backbone.View.prototype或类似代码,但我会将其留给别人去做。
答案 1 :(得分:4)
我将子视图存储在数组中,当我关闭“父”视图时,通过视图的close()
函数,迭代数组并关闭子视图。
这要求Subview1和Subview2也具有close()
功能。
Home = Backbone.View.extend({
template: "static/js/templates/home.html",
initialize: function() {
_.bindAll(this);
this.render();
// Hold sub views
this.views = [];
},
close: function() {
this.remove();
this.unbind();
this.clear_views();
},
clear_views: function() {
while this.views.length > 0
this.views[0].close()
this.views.splice(0, 1)
},
render: function() {
var view = this;
// Fetch the template, render it to the View element and call done.
namespace.fetchTemplate(this.template, function(tmpl) {
view.el.innerHTML=tmpl();
view.subRender();
});
return this;
},
subRender: function() {
var view = this;
var videoView = new Subview1({
el: $('#wrapper1'),
homeView: view
});
this.views.push(videoView);
var timeView = new Subview2({
el: $("#wrapper2")
});
this.views.push(timeView);
}
});