Angular Renderer2 remove listener оставляет EventListeners в памяти - утечка памяти?
У меня есть 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 слушателя).
Есть идеи, это утечка памяти или как их убрать?
1 ответ
Хммм... кажется, вы используете Angular в режиме разработки. Ваши EventListeners могут быть присоединены к Angular's DebugElement
, Если вы создаете и удаляете узлы с помощью Renderer2, вы также можете заметить, что все ваши Detached HTMLElement
с сохраняются в памяти.
Не беспокойтесь слишком сильно, потому что все это исчезает в режиме Prod.
Кстати, в чем преимущество добавления слушателей через рендерер?
Это избавляет вас от необходимости вручную удалять прослушиватели событий. Если вы используете addEventListener
а также removeEventListener
с чистым JavaScript, вы должны будете назвать свою функцию слушателя. Также будет сложно передавать параметры класса, если вам нужно выполнить некоторые манипуляции с данными: Как передать аргументы функции прослушивателя addEventListener?
Renderer-х listen
Метод поддерживает прослушивание и прослушивание анонимных функций, поддерживает функции класса, которые ссылаются на класс компонента (который addEventListener
не поддерживает - используя addEventListener
, this
будет указывать на целевой элемент, а не на класс компонента) и легко поддерживает вызов функций слушателя с дополнительными аргументами. Это универсально и безопасно, если вы помните, чтобы не слушать.
Кроме того, механика unlisten в Angular более надежна, чем вызов removeEventListener
, removeEventListener
требует, чтобы разработчик предоставил точные параметры, может легко потерпеть неудачу и не имеет возвращаемого значения или уведомления, чтобы сообщить вам, успешно ли вы удалили что-то. С Renderer2 вы практически гарантированно удаляете правильный EventListener.