我在指令中有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个监听器)。
有什么想法是内存泄漏或如何清除?
答案 0 :(得分:0)
嗯...看来您正在开发模式下运行Angular。您的EventListener可能会附加到Angular的DebugElement
上。如果使用Renderer2创建和删除节点,您可能还会注意到所有Detached HTMLElement
都保留在内存中。
不要太担心,因为这一切在生产模式下都会消失。
顺便说一句,通过渲染器添加侦听器有什么优势?
它免除了您手动删除事件侦听器的麻烦。如果将addEventListener
和removeEventListener
与纯JavaScript一起使用,则必须命名您的侦听器函数。如果您需要执行一些数据操作,那么传递类参数也很麻烦:How to pass arguments to addEventListener listener function?
Renderer的listen
方法支持监听和取消监听匿名函数,支持引用您的组件类的类函数(addEventListener
不支持-使用addEventListener
,this
指向目标元素,而不是您的组件类),并轻松支持使用附加参数调用侦听器函数。它用途广泛且安全,可让您记得取消收听。
此外,Angular的不监听机制比调用removeEventListener
更可靠。 removeEventListener
要求开发人员提供确切的参数,很容易失败,并且没有返回值或通知您是否已成功删除某些内容。使用Renderer2,实际上可以确保您删除了正确的EventListener。