typescript 在 ngOnDestroy 中删除 EventListener

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39755007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:53:01  来源:igfitidea点击:

Removing EventListener in ngOnDestroy

angulartypescript

提问by ShellZero

I have the following implementation of a directive. How to removeEventListener in this case:

我有以下指令的实现。在这种情况下如何删除EventListener:

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 I can simply use a global variable here and can access it. But I don't want to store the state of instance in the global variable.

我知道我可以在这里简单地使用一个全局变量并可以访问它。但我不想将实例的状态存储在全局变量中。

回答by yurzui

I would leverage @HostListenerdecorator to do that:

我会利用@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) { }
} 

The handler will be automatically removed in ngOnDestroy.

处理程序将在ngOnDestroy.

For other solutions see:

有关其他解决方案,请参阅:

回答by ShellZero

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

干杯,深圳

回答by VRPF

Make it like this:

让它像这样:

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

回答by superjos

As of today, the "Angular way" is to inject a Renderer2dependency and work with that, to abstract away actual DOM manipulation when working on a platform different than browser (e.g. native or server-side rendering).

截至今天,“Angular 方式”是注入一个Renderer2依赖项并使用它,以便在与浏览器不同的平台上工作时抽象出实际的 DOM 操作(例如本机或服务器端渲染)。

See this SO answer.

请参阅此 SO 答案

回答by micronyks

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

工作演示:https: //plnkr.co/edit/ZYnlruYQ2HwrQpHZqV9O?p =preview

NOTE: In DEMO, I use blur eventinstead of ngDestroy. (which serve the same purpose). If you type anything in textbox, it will listen to keyup eventbut as you come out from textbox input , blur eventhappens and no further keyupwill get fired.

注意:在演示中,我使用blur 事件而不是ngDestroy。(用于相同的目的)。如果您在文本框中键入任何内容,它将侦听keyup 事件,但是当您从文本框 input 中出来时,会发生模糊事件,并且不会触发进一步的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); 
    }    
}