Angular Renderer2删除侦听器会将EventListeners留在内存中-内存泄漏?

时间:2018-10-31 10:53:43

标签: angular memory-leaks angular6 angular2-directives angular-renderer2

我在指令中有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个监听器)。

enter image description here

有什么想法是内存泄漏或如何清除?

1 个答案:

答案 0 :(得分:0)

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

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

  

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

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

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

此外,Angular的不监听机制比调用removeEventListener更可靠。 removeEventListener要求开发人员提供确切的参数,很容易失败,并且没有返回值或通知您是否已成功删除某些内容。使用Renderer2,实际上可以确保您删除了正确的EventListener。