1

我在指令中有 3 个事件监听器,我在按钮切换和删除时添加和删除

private addListeners() {
    this.mouseLeaveFunc = this.renderer.listen(this.el.nativeElement, 'mouseleave', () => {

    });
    this.mouseEnterFunc = this.renderer.listen(this.el.nativeElement, 'mouseenter', () => {

    });
    this.onClickFunc = this.renderer.listen(this.el.nativeElement, 'click', (event) => {

    });
}

 private removeListeners() {
    if (this.mouseLeaveFunc) {
        this.mouseLeaveFunc();
        this.mouseEnterFunc();
        this.onClickFunc();
    }
}

监听器删除后,Angular 不再监听它们,但是比较第一次单击和第二次单击后获取的内存转储,我发现第二个有 9 个监听器(我在页面上有 3 个指令,所以 3 el x 3 个监听器)。

在此处输入图像描述

有什么想法是内存泄漏还是如何删除它们?

4

1 回答 1

1

嗯...看来您正在开发模式下运行 Angular。您的 EventListeners 可能附加到 Angular 的DebugElement. 如果您使用 Renderer2 创建和删除节点,您可能还会注意到您的所有Detached HTMLElements 都保留在内存中。

不要太担心,因为这一切都会在 prod 模式下消失。

顺便说一句,通过渲染器添加侦听器有什么好处?

它为您省去了手动删除事件侦听器的麻烦。如果您使用纯 JavaScript addEventListenerremoveEventListener则必须命名您的侦听器函数。如果您需要执行一些数据操作,传递类参数也会很痛苦:How to pass arguments to addEventListener listener function?

Renderer 的listen方法支持监听和不监听匿名函数,支持引用你的组件类的类函数(addEventListener不支持 - using addEventListenerthis将指向目标元素,而不是你的组件类),并且轻松支持使用附加参数调用监听器函数。它用途广泛且安全,让您记住不听。

此外,Angular 的 unlisten 机制比 call 更可靠removeEventListenerremoveEventListener需要开发人员提供准确的参数,很容易失败,并且没有返回值或通知告诉您是否已成功删除某些内容。使用 Renderer2,您实际上可以保证您正在删除正确的 EventListener。

于 2018-11-06T02:59:40.980 回答