【问题标题】:Unable to removeEventListener in angular directive无法在角度指令中删除事件监听器
【发布时间】:2020-01-30 09:43:15
【问题描述】:

我试图阻止在按 f5 时重新加载整个页面。 我创建了一个指令,当按下 f5 时单击按钮,这有效,但是我无法删除此事件

https://stackblitz.com/edit/angular-wpok2b

HTML:

<button appClickf5 disabled *ngIf="show">will be clicked if f5</button>
<br/><br/><br/>
<button (click)="show = !show">toggle init/destroy</button>
<div id="output"></div>

指令:

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

@Directive({
  selector: '[appClickf5]'
})
export class Clickf5Directive  implements OnInit, OnDestroy {

  constructor(private _el: ElementRef) { }

  ngOnInit() {
    this.log("init")
    document.addEventListener("keydown", this.callback.bind(this));
  }

  ngOnDestroy() {
    this.log("ngOnDestroy")
    document.removeEventListener("keydown", this.callback.bind(this));
  }

  callback(e: KeyboardEvent) {
    if ((e.code === "F5" || e.key === "F5") && e.ctrlKey === false) {
      e.preventDefault();
      this._el.nativeElement.click();
      this.log("element clicked");
    }
  }

  private log(txt){
    document.getElementById("output").innerHTML+="<br/>"+txt;
  }
}

有什么想法吗?

【问题讨论】:

    标签: angular angular-directive


    【解决方案1】:

    使用反应式方法更容易实现:

    @Directive({
      selector: '[appClickf5]',
    })
    export class Clickf5Directive implements OnInit, OnDestroy {
      private destroyed$: Subject<void> = new Subject();
    
      constructor(private _el: ElementRef) {}
    
      public ngOnInit() {
        fromEvent(document, 'keydown').pipe(
          filter(
            (e: KeyboardEvent) =>
              (e.code === 'F5' || e.key === 'F5') && e.ctrlKey === false
          ),
          tap((e: KeyboardEvent) => {
            e.preventDefault();
            this._el.nativeElement.click();
          }),
          takeUntil(this.destroyed$)
        ).subscribe();
      }
    
      public ngOnDestroy() {
        this.destroyed$.next();
        this.destroyed$.complete();
      }
    }
    

    我只用 rxjs 做了一个现场演示,前 5 秒它确实会捕获事件并阻止刷新。 5s后可以刷新页面:

    https://stackblitz.com/edit/rxjs-rfylfi?file=index.ts

    要试一试,你必须使用:

    否则将重新加载 stackblitz 应用程序,而不是应用程序本身

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      相关资源
      最近更新 更多