如何清除 Backbone.js 僵尸视图

a5g8bdjr  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(171)

我正在尝试制作我的第一个搜索应用程序。
在应用程序构建完成后,每个DOM都按照我的预期进行渲染,事件也正常工作。当我深入研究它时,我发现了一个奇怪的行为,在我做了一些搜索后,我发现这是因为 * 僵尸视图 * 事件委托问题。
下面是我的部分代码:

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

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

显示列表.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,并试图了解和修复我的问题,也试图在showList.js中添加this.remove(),正如有人提到的,但不幸的是,可能是因为我无法将它们放在我的代码中的适当位置,问题仍然没有解决。

dtcbnfnu

dtcbnfnu1#

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

不要共享页面中的相同元素

您正在创建绑定到页面中同一元素的新ShowList示例。在Backbone中,这是不好的做法。
每个Backbone View示例都有自己的根元素,事件绑定在该元素上。当多个视图共享同一个元素时,事件会在每个示例上触发,并且您不能在视图上调用remove,因为它会将DOM元素从页面中完全删除。
您应该转储要重用的元素中的子视图根元素。

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

重复使用视图

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);
    }
});

这是一个关于重用视图而不是总是创建一个新视图的超级基本示例。

有必要进行一些清理

当完成一个视图时,应该在它上面调用remove
从DOM中移除视图及其el,并调用stopListening以移除视图具有listenTo的任何绑定事件。
要使其正常工作,当注册模型或集合事件的回调时,use listenTo over on or bind可避免其他内存泄漏(或僵尸视图)。
对于具有多个子视图的视图,一个好的模式是保留每个子视图的引用,并在删除父视图时对每个子视图调用remove
查看如何avoid memory leaks when rendering list views。当处理大量视图(大列表或视图树)时,有一些efficiently render with Backbone的方法,其中涉及DocumentFragment批处理和延迟。

相关问题