如何清除 Backbone 僵尸视图

How to clear Backbone zombie views

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

构建应用程序后,每个 DOM 都按照我的预期呈现,事件也正常工作。当我深入研究它时,我发现了一个奇怪的行为,经过一番搜索,我发现这是因为 zombie view 事件委托问题。

这是我的部分代码:

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'按钮事件与之绑定。

所以像'zombie'一样,多次点击提交后,再点击'.testing'按钮,console.log()会输出多次

我已经关注了文章 here 并试图理解和解决我的问题,并且还尝试像有人提到的那样在 showList.js 中添加 this.remove(),但不幸的是,这可能是因为我无法将它们放在我的代码中的正确位置,问题仍未解决。

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

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

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

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

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

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

重用视图

render function should be 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

Removes a view and its el from the DOM, and calls stopListening to remove any bound events that the view has listenTo'd.

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

具有多个子视图的视图的一个好模式是保留每个子视图的引用,并在父视图被删除时对每个子视图调用 remove

了解如何 . When dealing with a lot of views (big list or tree of views), there are ways to which involves DocumentFragment 批处理和延迟。