JavaScript removeEventListener OnDestroy无法在Angular 6中运行

时间:2018-11-16 18:49:22

标签: angular typescript angular-routing

我正在尝试用removeEventListener的角度系数:Javascript removeEventListener not working

    ...
    ngOnInit() {
        document.addEventListener('visibilitychange', () =>this.handleVisibleState(), true);
    }

    ngOnDestroy() {
        document.removeEventListener('visibilitychange', () => this.handleVisibleState(), true);
    }

    handleVisibleState() {
        let vis = document.visibilityState === 'visible';
        this.configsService.update_collab_visible(vis);
    }
    ...
具有以上addEventListener

即使在ngOnDestroy ()后仍然有效

如何从角度组件中的文档中解除可见性状态?

尝试2

    private visibilityChangeCallback: () => void;

    ngOnInit() {
        this.visibilityChangeCallback = () => this.handleVisibleState();
        document.addEventListener('visibilitychange', this.handleVisibleState, true);
    }

    ngOnDestroy() {
        document.removeEventListener('visibilitychange', this.handleVisibleState, true);
    }

    handleVisibleState() {
        let vis = document.visibilityState === 'visible';
        console.log(typeof this.configsService); // undefined
        this.configsService.update_collab_visible(vis);
    }

结果:

  

错误TypeError:无法读取未定义的属性'update_collab_visible'

4 个答案:

答案 0 :(得分:2)

您必须使用箭头函数将函数设置为类的属性字段,并且不能使用匿名函数,因为函数引用将不同。

出现Cannot read property 'update_collab_visible' of undefined错误的原因是因为您使用的是类函数而不是类字段。这会将this上下文移到该函数上,而不是您想要的:

ngOnInit() {
    document.addEventListener('visibilitychange', this.handleVisibleState, true);
}

ngOnDestroy() {
    document.removeEventListener('visibilitychange', this.handleVisibleState, true);
}

handleVisibleState = () => {
    let vis = document.visibilityState === 'visible';
    this.configsService.update_collab_visible(vis);
};

还有其他选择。我看到您想为事件使用捕获标志。您也可以考虑使用rxjs lib:

destroy = new Subject<void>();

ngOnInit() {
  fromEvent(document, 'visibilitychange', true).pipe(
    takeUntil(this.destroy)
  ).subscribe((event) => this.handleVisibleState(event));
}

ngOnDestroy() {
  this.destroy.next();
  this.destroy.complete();
}

广告

还有一个角度库,它为模板和组件事件绑定添加了功能,称为ng-event-options。如果已安装/导入了该文件,则只需使用:

@HostListener('document:visibilitystate.c')
handleVisibleState() {
    let vis = document.visibilityState === 'visible';
    this.configsService.update_collab_visible(vis);
}

您已经完成

答案 1 :(得分:1)

存储回调:

private visibilityChangeCallback: () => void;

ngOnInit() {
    this.visibilityChangeCallback = () => this.handleVisibleState();
    document.addEventListener('visibilitychange', this.visibilityChangeCallback, true);
}

ngOnDestroy() {
    document.removeEventListener('visibilitychange', this.visibilityChangeCallback, true);
}

答案 2 :(得分:1)

使用无法标识EventTarget上任何当前注册的EventListener的参数调用removeEventListener()无效。您正在为此传递其他功能。

使用instance arrow function应该对您有帮助:

ngOnInit() {
    document.addEventListener('visibilitychange', this.handleVisibleState, true);
}

ngOnDestroy() {
    document.removeEventListener('visibilitychange', this.handleVisibleState, true);
}

handleVisibleState = () => {
    let vis = document.visibilityState === 'visible';
    this.configsService.update_collab_visible(vis);
}

答案 3 :(得分:0)

this.<anything>不起作用的原因是this的含义不同,因为它在回调中,并且您没有绑定它。

如果您bind this应该可以工作。

document.addEventListener('visibilitychange', this.handleVisibleState.bind(this), true);