Невозможно удалитьEventListener в директиве angular - PullRequest
1 голос
/ 30 января 2020

Я пытаюсь предотвратить перезагрузку всей страницы при нажатии клавиши 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;
  }
}

Есть идеи?

1 Ответ

2 голосов
/ 30 января 2020

Этого легче добиться с помощью реактивного подхода:

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

Я сделал живую демонстрацию только с rx js, в течение первых 5 секунд она ловит события и предотвращает повторное обновление sh. Через 5 секунд вы можете обновить sh страницу:

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

Чтобы попробовать, вы должны использовать:

enter image description here

в противном случае будет перезагружено приложение stackblitz, а не само приложение

...