【发布时间】:2016-01-21 03:04:58
【问题描述】:
我正在考虑从原版 Backbone 迁移到 Marionette,就像 Backbone 一样,我首先要确保我没有内存泄漏,因为我正在构建一个单页应用程序。
使用 Backbone 调试器,我可以看到,当我更改 LayoutView 区域中显示的视图时,HTML 确实被破坏了,但模型和/或集合永远保留在内存中。
首先,这是我的 PostController 代码:
var PostController = Marionette.Object.extend({
showOne: function(post_cd){
// layoutView
var postView = new PostView();
// Create data containers
var comments = new Comments(); // This is a Backbone.Collection
var post = new Post(); // This is a Backbone.Model
// Create subviews (compositeView)
var commentsView = new CommentsView({collection: comments, model: post});
// Render the compositeView in the layoutView when displaying the layoutView
postView.on('before:show', function(region, view, options){
this.showChildView('comments', commentsView);
});
// Data init.
post.fetch();
comments.fetch();
// Show the view on the main region.
// app.layout is another LayoutView binded to <body>
app.layout.showChildView('main', postView);
}
});
接下来,我的 UserController 代码:
var UserController = Marionette.Object.extend({
showOne: function(userCd){
var user = new User({user_cd: userCd});
// Marionette.ItemView
var userItemView = new UserItemView({model: user});
// Fetch the user
user.fetch();
// Show the view on the main region
app.layout.showChildView('main', userItemView);
}
});
很简单,我只是创建一个模型/集合和一个关联的视图,然后在我的“主要”区域中切换它们。
以下是我非常简单的观点:
一、UserItemView(在UserController中使用):
var UserItemView = Marionette.ItemView.extend({
tagName: 'div',
template: "<a href='#post/48' id='goToPost'>Go to post 48.</a>",
events:{
"click #goToPost": "goToPost",
},
goToPost: function(e){
e.preventDefault();
app.testRouter.triggerMethod('post:show', 48);
}
});
我的复合视图“CommentsView”(用于 PostController):
var CommentsView = Marionette.CompositeView.extend({
childView: CommentItemView,
childViewContainer: "#comments_list",
tagName: 'div',
id: 'comments',
template: '<ul id="comments_list"></ul><a href="#" id="goToUser">Go to user 20.</a>',
ui: {
userLink: '#goToUser'
},
events:{
"click @ui.userLink": "goToUser"
},
goToUser: function(e){
e.preventDefault();
app.testRouter.triggerMethod('user:show', 20);
}
});
这些是 Backbone Debugger 的结果:
1) 在帖子页面打开应用:
正如预期的那样,3 个模型。一个帖子(模特)和2个cmets(收藏)。
2) 导航到我的“用户”页面:
旧视图被正确移除并添加新视图。
我的 3 个旧模型还在!和我的新人一起。
即使此页面没有使用任何集合,帖子页面中的旧集合仍然存在。
我错过了什么吗?我应该手动清除那些 onDestroy() 吗?如果是这样,如何?我尝试删除并设置为 null,但这些都不起作用。
我也用Heap snapshots查看了在页面之间点击了一段时间后的内存差异,确实是无限涨了。
谢谢。
【问题讨论】:
-
为什么会因为视图从 DOM 中删除而自动销毁任何集合或模型?
-
我不了解木偶,但即使在删除视图后,您的控制器仍保留对这些集合/模型的引用,对吗?
-
@ivami,模型不应该像从服务器中删除那样被销毁,但应该从内存中删除。 TJ,它们是用 var 在本地分数中创建的,所以当视图被销毁时,它们不再被引用,应该被删除。
标签: backbone.js memory-leaks marionette