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.

Другие вопросы по тегам