删除或销毁事件监听器

use*_*3 ツ 3 javascript event-listener addeventlistener angular

angular2应用程序上工作。我有RxJS计时器实例,该实例将在登录时向用户推送通知。但是,如果选项卡未处于活动状态,则不应推送通知,则调度程序应暂停/停止。也完成了。

但是主要的是,我已经将该窗口(焦点,模糊)事件侦听器添加到ngOnInit()中。当我们更改页面/组件时,我尝试在ngOnDestroy()上销毁它,但它也不会停止。当我们回到同一页面时,该侦听器的第二个实例也开始运行,现在我的内存/作用域中将有2个调度程序实例。

因此,任何人都知道如何在ngOnDestroy或任何其他地方删除/销毁window.listener !

码:

timerFlag: boolean = true;
private timer;
private sub: Subscription;

ngOnInit() {
    this.sub = null;
    this.timer = null;
    console.log("home-init");
    window.addEventListener('blur', this.disableTimer.bind(this), false);
    window.addEventListener('focus', this.initializeTimer.bind(this), false);
}
disableTimer() {
    if (this.sub !== undefined && this.sub != null) {
        this.sub.unsubscribe();
        this.timer = null;
    }
}
initializeTimer() {
    if (this.timerFlag) {
        if (this.timer == null) {
            this.timer = Observable.timer(2000, 5000);
            this.sub = this.timer.subscribe(t => this.runMe());
        }
    }
}
runMe() {
    console.log("notification called : " + new Date());
}
ngOnDestroy() {
    console.log("Destroy timer");
    this.sub.unsubscribe();
    this.timer = null;
    this.sub = undefined;
    this.timerFlag = false;
    window.removeEventListener('blur', this.disableTimer.bind(this), false);
    window.removeEventListener('focus', this.initializeTimer.bind(this), false);
}
Run Code Online (Sandbox Code Playgroud)

谁能指导我如何销毁事件侦听器实例,以便下次下次访问同一页面时不会启动第二个实例。

我已经尝试在启动窗口侦听器之前在ngOnInit中删除侦听器

yur*_*zui 5

1)我想这应该工作:

ngOnInit() {
  window.addEventListener('blur', this.disableTimer, false);
  window.addEventListener('focus', this.initializeTimer, false);
}

disableTimer = () => { // arrow function
  ...
}
initializeTimer = () => { // arrow function
  ... 
}

ngOnDestroy() {
  window.removeEventListener('blur', this.disableTimer, false);
  window.removeEventListener('focus', this.initializeTimer, false);
}
Run Code Online (Sandbox Code Playgroud)

柱塞示例

2)另一种方法是将侦听器存储在变量中,因为.bind每次都会返回新函数

disableTimerFn: EventListenerOrEventListenerObject;

ngOnInit() {
  this.disableTimerFn = this.disableTimer.bind(this);
  window.addEventListener('blur', this.disableTimerFn, false); 
}

ngOnDestroy() {
  window.removeEventListener('blur', this.disableTimerFn, false);
}
Run Code Online (Sandbox Code Playgroud)

柱塞示例

3)但也许最好的方法是使用angular2方法:

@HostListener('window:blur', ['$event'])
disableTimer (event) { ... }
Run Code Online (Sandbox Code Playgroud)

销毁组件时,它将自动删除

柱塞示例

4)另一种angular2方式是使用Renderer

globalListenFunc: Function;
constructor(private renderer: Renderer) { }
ngOnInit() {
  this.globalListenFunc = this.renderer.listenGlobal('window', 'click', this.onClick.bind(this))
}

onClick() {
  alert('click');
}

ngOnDestroy() {
  this.globalListenFunc(); // destroy listener
}
Run Code Online (Sandbox Code Playgroud)

柱塞示例

也可以看看