【问题标题】:Marionette not clearing models and collection on destroy()Marionette 没有在 destroy() 上清除模型和集合
【发布时间】: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


【解决方案1】:

事实证明,我被 Backbone 调试器控制,它似乎使实例保持活动状态,因此您可以继续监视/检查它们。 Marionette explorer 也有同样的缺陷。

我禁用了它们并在我的堆配置文件中寻找我的主干对象,发现它的行为正常。

对于那些有同样问题的人,要在堆配置文件中查找主干对象,不要搜索“backbone”、“model”或其他任何内容,而是搜索“child”。 由于控制器的工作方式,所有主干对象都在“子”下。

【讨论】:

    猜你喜欢
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    相关资源
    最近更新 更多