javascript Backbone JS:导航到另一个 url 时如何清理视图?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9960353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Backbone JS: How to clean up views when navigate to another url?
提问by user469652
I have a Homeview that contains a few subviews on page, when I navigate to another page using the router, how can I clean existing views, and build new views for the page I want to navigate to?
我有一个主页视图,其中包含页面上的一些子视图,当我使用路由器导航到另一个页面时,如何清理现有视图,并为要导航到的页面构建新视图?
This application has no model/collections, just views.
此应用程序没有模型/集合,只有视图。
Thank you!
谢谢!
Part of the code:
部分代码:
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")
});
}
});
采纳答案by obmarg
You could probably just use backbone's events mechanism to do this if you wanted.
如果您愿意,您可能只使用主干的事件机制来执行此操作。
You'd just need to create a global event router, and then have each of your views listen for a CloseView
event. Then you just need to perform all your shutdown on receiving the CloseView
event.
您只需要创建一个全局事件路由器,然后让您的每个视图监听一个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.
}
});
Then it's just a case of calling dispatcher.trigger( 'OnClose' )
in your router/elsewhere to trigger the close functions.
那么这只是dispatcher.trigger( 'OnClose' )
在您的路由器/其他地方调用以触发关闭功能的一种情况。
As a shortcut, assuming you wanted to perform this shutdown on every navigation, you could just register for events on the router (either a custom 'OnClose' event as here, or the 'all' event to just get every navigation) though you would have to be careful that the events were called in the order you were expecting.
作为一种快捷方式,假设您想在每次导航时执行此关闭操作,您可以只在路由器上注册事件(此处是自定义的“OnClose”事件,或者只是获取每个导航的“全部”事件),尽管您会必须注意事件是按照您期望的顺序调用的。
It'd also probably be possible to refactor some of this code into Backbone.View.prototype or similar, but I'll leave that for someone else to do.
也可以将其中的一些代码重构为 Backbone.View.prototype 或类似代码,但我会将其留给其他人来做。
回答by Edward M Smith
I store sub-views in an array and when I close a "parent"-view, via the view's close()
function, iterate over the array and close the sub-views.
我将子视图存储在一个数组中,当我关闭“父”视图时,通过视图的close()
函数,遍历数组并关闭子视图。
This requires Subview1 and Subview2 to have close()
functions as well.
这需要 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);
}
});