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

Angular微前端(MFE)调用对话框组件时MAT_DIALOG_DATA注入失败求助

解决Angular微前端中远程组件注入MAT_DIALOG_DATA失败的问题

问题场景

在Angular宿主应用中加载另一个Angular项目的远程模块,加载代码如下:

loadRemoteModule({
      remoteEntry: 'https://localhost:3028/sremoteEntry.js',
      remoteName: 'mfe1',
      exposedModule: './MyModule',
    })
      .then(m => {
        const myComponent= m.MyModule.ɵmod.declarations[0];
        this._dialogRef = this._dialog.open(myComponent, {
          data: eeData,
          disableClose: false,
          width: '990px',
          height: '495px',
          autoFocus: false,
        });

        return m.MyModule;
      })

远程组件的构造函数依赖@Inject(MAT_DIALOG_DATA) public dialogData: any,打开对话框时提示MdcDialogData未提供。已确认所有公共依赖均设置为singleton:true共享,且尝试过以下方案:

  • 在远程模块和宿主模块中都引入MatDialogModule
  • 静态提供MAT_DIALOG_DATA(设置useValue: {})——此方案可行,但无法传递宿主端的eeData

解决方案

方案一:通过自定义注入器传递令牌

直接调用_dialog.open()传递data在微前端场景下会因为注入上下文隔离失效,需要手动创建组件工厂并提供令牌:

loadRemoteModule({
  remoteEntry: 'https://localhost:3028/sremoteEntry.js',
  remoteName: 'mfe1',
  exposedModule: './MyModule',
})
.then(async (m) => {
  // 编译并创建远程模块的NgModule实例
  const moduleFactory = await this._compiler.compileModuleAsync(m.MyModule);
  const moduleRef = moduleFactory.create(this._injector);

  // 获取目标组件类
  const myComponent = m.MyModule.ɵmod.declarations[0];
  // 创建组件工厂
  const componentFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(myComponent);

  // 构建包含MAT_DIALOG_DATA的自定义注入器
  const injector = Injector.create({
    parent: this._injector,
    providers: [
      { provide: MAT_DIALOG_DATA, useValue: eeData }
    ]
  });

  // 打开对话框时传入自定义注入器
  this._dialogRef = this._dialog.open(myComponent, {
    data: eeData, // 保留此字段确保MatDialog内部逻辑兼容
    disableClose: false,
    width: '990px',
    height: '495px',
    autoFocus: false,
    injector: injector // 关键:传递自定义注入器
  });

  return m.MyModule;
})

方案二:直接暴露组件而非模块

如果远程模块仅需提供该对话框组件,可简化为直接暴露组件类,避免模块上下文的注入隔离问题:

  1. 修改远程模块的webpack配置,调整暴露内容:
module.exports = {
  // 其他配置...
  exposes: {
    './MyComponent': './src/app/my-component/my-component.component.ts'
  }
};
  1. 宿主端加载代码调整为:
loadRemoteModule({
  remoteEntry: 'https://localhost:3028/sremoteEntry.js',
  remoteName: 'mfe1',
  exposedModule: './MyComponent',
})
.then(({ MyComponent }) => {
  // 构建包含MAT_DIALOG_DATA的自定义注入器
  const injector = Injector.create({
    parent: this._injector,
    providers: [
      { provide: MAT_DIALOG_DATA, useValue: eeData }
    ]
  });

  this._dialogRef = this._dialog.open(MyComponent, {
    data: eeData,
    disableClose: false,
    width: '990px',
    height: '495px',
    autoFocus: false,
    injector: injector
  });
})

关键注意事项

确保@angular/material相关包(尤其是@angular/material/dialog)在宿主和远程模块的webpack共享配置中均设置为singleton: true,避免因依赖重复实例化导致注入令牌不匹配。

内容的提问来源于stack exchange,提问作者Abhishek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:46:11