Angular14组件window message事件重复绑定问题求助
解决Angular 14中window message事件回调多次执行的问题
问题根源
你遇到的核心问题是:this.test.bind(this)每次调用都会返回一个全新的函数实例。这意味着你每次添加监听器时传入的函数,和你在ngOnDestroy里试图移除的this.test不是同一个引用,导致监听器根本没被删掉。每次组件初始化都会新增一个监听器,触发事件时自然会执行多次回调。
解决方案1:保存绑定后的函数引用
在组件类中提前保存绑定好this的函数引用,确保添加和移除监听器时用的是同一个函数:
export class YourComponent implements OnInit, OnDestroy { // 保存绑定好this的回调函数引用 private boundTest: (event: any) => void; ngOnInit(): void { // 一次性绑定this并保存引用 this.boundTest = this.test.bind(this); // 使用保存的引用添加监听器 if (window.addEventListener) { window.addEventListener('message', this.boundTest); } else { (<any>window).attachEvent('onmessage', this.boundTest); } } test(event: any): void { if (event.data !== undefined) { if (event.data.msg === 'test') { return; } if (event.data.msg === 'check') { this.dosomething(); } } } ngOnDestroy(): void { // 使用同一个引用移除监听器 if (window.removeEventListener) { window.removeEventListener('message', this.boundTest); } else { (<any>window).detachEvent('onmessage', this.boundTest); } } }
解决方案2:使用箭头函数(更简洁)
箭头函数会自动继承当前组件的this上下文,而且它的函数引用是固定的,不会每次调用生成新实例:
export class YourComponent implements OnInit, OnDestroy { // 用箭头函数定义回调,自动绑定this private test = (event: any): void => { if (event.data !== undefined) { if (event.data.msg === 'test') { return; } if (event.data.msg === 'check') { this.dosomething(); } } } ngOnInit(): void { // 直接传入this.test,引用固定 if (window.addEventListener) { window.addEventListener('message', this.test); } else { (<any>window).attachEvent('onmessage', this.test); } } ngOnDestroy(): void { // 直接移除this.test即可匹配 if (window.removeEventListener) { window.removeEventListener('message', this.test); } else { (<any>window).detachEvent('onmessage', this.test); } } }
额外说明
- 推荐在
ngOnInit中添加监听器,而非构造函数——构造函数执行时组件未完成初始化,Angular生命周期钩子更适合处理这类操作。 - 可去掉IE兼容代码:支持Angular 14的现代浏览器均支持标准
addEventListener,无需兼容attachEvent。
内容的提问来源于stack exchange,提问作者Deepa Desai
相关产品推荐
相关产品推荐

