Удаление EventListener в ngOnDestroy

У меня есть следующая реализация директивы. Как removeEventListener в этом случае:

import { Directive, ElementRef, OnDestroy } from "@angular/core";

@Directive({
    selector: "[Enter]"
})
export class Enter implements OnDestroy{
    constructor(el: ElementRef) {
        let enter = function(event){
            if(event.keyCode === 13){
                el.nativeElement.click();
            }
        }
        document.addEventListener('keyup', enter , false);
    }

    ngOnDestroy(){
        document.removeEventListener('keyup', enter, false); //this line doesn't work because I can't access enter variable here!
    }
}

Я знаю, что могу просто использовать глобальную переменную здесь и получить к ней доступ. Но я не хочу хранить состояние экземпляра в глобальной переменной.

5 ответов


Это должно решить проблему:

import { Directive, ElementRef, OnDestroy } from "@angular/core";

@Directive({
    selector: "[Enter]"
})
export class Enter implements OnDestroy{
    private enter;
    constructor(el: ElementRef) {
        this.enter = function(event){
            if(event.keyCode === 13){
                el.nativeElement.click();
                console.log("enter triggered");
            }
        }
        document.addEventListener('keyup', this.enter , false);
        console.log("Added event listener");
    }

    ngOnDestroy(){
        document.removeEventListener('keyup', this.enter, false);
        console.log("Removed event listener"); 
    }
}

надеюсь, что это помогает.

Ура, SZ


Я хотел бы использовать @HostListener декоратор, чтобы сделать это:

@Directive({
  selector: "[Enter]"
})
export class Enter {
  @HostListener('document:keyup', ['$event'])
  enter(event) {
    if (event.keyCode !== 13) return;
    this.el.nativeElement.click();
  }
  constructor(private el: ElementRef) { }
} 

обработчик будет автоматически удален в ngOnDestroy.

для других решений см.:


делается это так:

import { Directive, ElementRef, OnDestroy } from "@angular/core";

@Directive({
    selector: "[Enter]"
})
export class Enter implements OnDestroy{

    private enter: (event: KeyboardEvent) => void;

    constructor(el: ElementRef) {
        this.enter = (event) => {
            if(event.keyCode === 13){
                el.nativeElement.click();
            }
        }
        document.addEventListener('keyup',  this.enter , false);
    }

    ngOnDestroy(){
        document.removeEventListener('keyup', this.enter, false);
    }
}

на сегодняшний день "угловой путь" впрыснуть Renderer2 зависимость и работа с этим, чтобы абстрагироваться от фактических манипуляций DOM при работе на платформе, отличной от браузера (например, родной или серверный рендеринг).

посмотреть это так ответ.


рабочая демо:https://plnkr.co/edit/ZYnlruYQ2HwrQpHZqV9O?p=preview

Примечание: в демо, я использую событие размытость вместо ngDestroy. (которые служат той же цели). Если вы введете что-нибудь в textbox, он будет слушать событие keyup но как вы выходите из ввода textbox,событие размытость бывает и не дальше keyup уволят.

import { Directive, ElementRef, OnDestroy } from "@angular/core";

@Directive({
   selector: "[Enter]"
})
export class Enter implements OnDestroy{
    constructor(el: ElementRef) {
      var button=el.nativeElement;
      button.addEventListener('keyup',this.error)
    }

    error(event){
      console.log(event);
        //whatsoever
      if(event.keyCode === 13){
          el.nativeElement.click();
      }
    }

    ngOnDestroy(){
        button.removeEventListener('keyup',this.error); 
    }    
}