Removing EventListener in ngOnDestroy

I have the following implementation of the directive. How to remove the EventListener in this case:

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!
    }
}

I know that I can just use the global variable here and access it. But I do not want to save the state of the instance in a global variable.

+4
source share
5 answers

This should solve the problem:

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"); 
    }
}

Hope this helps.

Cheers, SZ

+3
source

I would use a @HostListenerdecorator to do this:

@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) { }
} 

The handler will be automatically deleted at ngOnDestroy.

For other solutions see

+17
source

:

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);
    }
}
+3

"Angular " , Renderer2 , DOM , (, ).

. SO.

+1

DEMO: https://plnkr.co/edit/ZYnlruYQ2HwrQpHZqV9O?p=preview

NOTE . In DEMO, I use blur instead of ngDestroy . (which serve the same purpose). If you enter something into the text field, it will listen for the keyup event , but as you exit the text field input , it will blur and more keyup will be fired.

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); 
    }    
}
0
source

Source: https://habr.com/ru/post/1656132/


All Articles