You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:25:24