Angular Renderer2 remove listener оставляет EventListeners в памяти - утечка памяти? - PullRequest
0 голосов
/ 31 октября 2018

У меня есть 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 голосов
/ 06 ноября 2018

Хммм ... кажется, вы используете Angular в режиме разработки. Ваши EventListeners могут быть присоединены к Angular's DebugElement. Если вы создаете и удаляете узлы с помощью Renderer2, вы также можете заметить, что все ваши Detached HTMLElement сохранены в памяти.

Не беспокойтесь слишком сильно, потому что все это исчезает в режиме Prod.

Кстати, в чем преимущество добавления слушателей через рендерер?

Это избавляет вас от необходимости вручную удалять прослушиватели событий. Если вы используете addEventListener и removeEventListener с чистым JavaScript, вам придется назвать функцию слушателя. Также будет сложно передавать параметры класса, если вам необходимо выполнить некоторые манипуляции с данными: Как передать аргументы в функцию прослушивателя addEventListener?

Метод listen Renderer поддерживает прослушивание и отмену прослушивания анонимных функций, поддерживает функции класса, которые ссылаются на класс компонента (который не поддерживается addEventListener - использование addEventListener, this будет указывать на целевой элемент, а не на ваш компонент класса) и легко поддерживает вызов функций слушателя с дополнительными аргументами. Он универсален и безопасен, при условии, что вы помните, чтобы не прослушать.

Кроме того, механизм прослушивания Angular более надежен, чем вызов removeEventListener. removeEventListener требует, чтобы разработчик предоставил точные параметры, может легко потерпеть неудачу и не имеет возвращаемого значения или уведомления, чтобы сообщить вам, успешно ли вы удалили что-то. С Renderer2 вы практически гарантированно удаляете правильный EventListener.

...