Angular renderer2 удалить слушателя оставляет 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 слушателя).

enter image description here

Есть идеи, это утечка памяти или как их удалить?

Кстати, когда я добавляю и удаляю таких слушателей событий, как this.el.nativeElement.addEventListener ('mouseleave', this.onMouseLeave); и сравнивая дамп памяти, слушателей не осталось. Кстати, в чем преимущество добавления слушателей через рендерер?

Vytautas Pranskunas 31.10.2018 13:13
1
1
1 925
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

Btw whats an advantage of adding listeners via renderer?

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

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

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

Спасибо за ответ, я тестировал его, и это действительно проблема режима разработки, и я понимаю вашу точку зрения, однако по поводу других вещей с некоторыми из ваших точек зрения я не согласен. "this" полностью поддерживается TypeScript путем передачи функции стрелки: this.el.nativeElement.addEventListener ('mouseleave', this.onMouseLeave); Удаление слушателя не может быть более надежным в Angular, потому что это оболочка и сбой, если он более распространен, потому что, как вы сказали, он поддерживает передачу параметров - с собственным прослушивателем событий есть только в параметре - событие, поэтому вы не можете потерпеть неудачу. Однако я поддерживаю идею использовать подход framewrok, а не чистый.

Vytautas Pranskunas 06.11.2018 15:44

Я имел в виду обернуть функцию класса анонимной функцией для передачи параметров. Также я подумал, что когда this.onMouseLeave ссылается, например, на this.otherClassParam, this внутри this.onMouseLeave относится к this.el.nativeElement. Думаю, тогда я ошибался :)

Jasmonate 07.11.2018 08:40

Привет, @Jasmonate, не могли бы вы предоставить какой-либо источник для этого «Не беспокойтесь слишком сильно, потому что все это исчезает в режиме prod».

Nikhil Kapoor 26.08.2019 06:52

Мне это тоже очень любопытно. К сожалению, это сильно замедляет работу моего приложения в dev.

Janis Jansen 09.08.2021 12:05

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