如何清除Backbone僵尸视图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何清除Backbone僵尸视图相关的知识,希望对你有一定的参考价值。

我正在尝试制作我的第一个搜索应用程序。

在构建应用程序之后,每个DOM都按照我的预期进行渲染,并且事件也可以正常工作。当我深入挖掘它时,我发现了一个奇怪的行为,在我做了一些搜索之后,我发现它是因为僵尸视图事件委托问题。

这是我的代码的一部分:

var searchList = Backbone.View.extend({
    events:{
        'click #submit':function() {
            this.render()
        }
    },
    render() {
        this.showList = new ShowList({el:$('.ADoM')});
    }
});

单击#submit时,将创建一个新的ShowList实例,并将呈现'.ADoM' DOM。

showList.js

var showList = Backbone.View.extend({

    events: {
        "click .testing": function(e) {
            console.log(e.currentTarget);
        },
    },
    initialize() {
        this.$el.html(SearchListTemplate());
    }
});

'.testing'按钮事件与它绑定。

因此,正如“僵尸”所做的那样,在多次点击提交后,然后点击'.testing'按钮,console.log()将输出多次。

我跟着文章here并试图理解并解决我的问题,并且还尝试在this.remove()中添加showList.js,就像有人提到的那样,但遗憾的是它可能因为我无法将它们放在我的代码中的适当位置,问题是仍未解决。

答案

这与ES6无关,这是基本的javascript和DOM操作。

Do not share the same element in the page

您正在创建新的ShowList实例,这些实例绑定到页面中的相同元素。在Backbone中,这是不好的做法。

每个Backbone View实例都有自己的根元素,事件绑定在该根元素上。当多个视图共享同一个元素时,会在每个实例上触发事件,并且您无法在视图上调用remove,因为它将完全从页面中删除DOM元素。

您应该将子视图根元素转储到要重用的元素中。

this.$('.ADoM').html(this.showList.render().el);

Reusing the view

render函数应该是idempotent

var searchList = Backbone.View.extend({
    events: {
        // you can use a string to an existing view method
        'click #submit': 'render'
    },
    initialize() {
        // instanciate the view once
        this.showList = new ShowList();
    },
    // This implementation always has the same result
    render() {
        this.$('.ADoM').html(this.showList.render().el);
        // Backbone concention is to return 'this' in the render function.
        return this;
    }
});

您的其他视图也可以简化,以反映父视图中的更改。

var showList = Backbone.View.extend({
    events: {
        "click .testing": 'onTestingClick',
    },
    // Don't render in the initialize, do it in the render function
    render() {
        this.$el.html(SearchListTemplate());
    },
    onTestingClick(e) {
        console.log(e.currentTarget);
    }
});

这是重用视图而不是始终创建新视图的超级基本示例。

A little cleanup is necessary

完成视图后,您应该在其上调用remove

从DOM中删除视图及其el,并调用stopListening以删除视图具有listenTo'd的任何绑定事件。

为此,在模型或集合事件上注册回调时,use listenTo over on or bind可以避免其他内存泄漏(或僵尸视图)。

具有多个子视图的视图的良好模式是保持每个子视图的引用,并在移除父视图时在每个子视图上调用remove

看看如何avoid memory leaks when rendering list views。在处理大量视图(大列表或视图树)时,有一些方法可以使efficiently render with Backbone涉及DocumentFragment批处理和推迟。

以上是关于如何清除Backbone僵尸视图的主要内容,如果未能解决你的问题,请参考以下文章

Backbone.js:清除所有视图的最佳方法

如何正确渲染 Backbone.js 视图

僵死进程的清除

如何从片段外部清除/重置地图?

如何使用主干-stickit 处理重复视图元素

如何在 Backbone.js 中设置视图的 id?