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

如何在打开Angular Material弹窗时向动态加载的子组件传参

实现步骤

第一步:定义通用注入令牌

专门用于传递动态组件的入参,新建popup-tokens.ts文件:

import { InjectionToken } from '@angular/core';

// 定义注入令牌,用于传递子组件参数
export const POPUP_CHILD_DATA = new InjectionToken<any>('POPUP_CHILD_DATA');

第二步:改造PopupShell组件,生成自定义注入器

修改popup-shell.component.ts

引入依赖并生成适配的注入器,把需要传给子组件的参数和MatDialog实例都注入到动态组件的上下文里:

import { Component, Inject, Injector } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { POPUP_CHILD_DATA } from './popup-tokens';

@Component({
  // 原有组件配置保持不变
  selector: 'app-popup-shell',
  templateUrl: './popup-shell.component.html'
})
export class PopupShellComponent {
  constructor(
    public dialogRef: MatDialogRef<PopupShellComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any,
    // 注入当前Injector作为父注入器
    private injector: Injector
  ) {}

  // 生成动态组件专用的注入器
  get componentInjector(): Injector {
    return Injector.create({
      parent: this.injector,
      providers: [
        // 传递子组件需要的自定义数据
        {
          provide: POPUP_CHILD_DATA,
          useValue: this.data.componentData
        },
        // 传递弹窗实例,方便子组件控制弹窗关闭、返回结果
        {
          provide: MAT_DIALOG_DATA,
          useValue: this.data
        }
      ]
    });
  }
}

修改popup-shell.component.html

给ngComponentOutlet绑定自定义注入器:

<mat-dialog-content class="mat-typography popup-shell">
    <div class="popup-shell__container">
        <ng-container *ngComponentOutlet="data.component; injector: componentInjector"></ng-container>
    </div>
</mat-dialog-content>

第三步:打开弹窗时传入子组件参数

调用open方法时在data里新增componentData字段,传入所有要给子组件的参数:

import { MatDialog } from '@angular/material/dialog';
import { PopupShellComponent } from './popup-shell.component';
import { UserPopupComponent } from './user-popup/user-popup.component';

// 你的业务组件代码
constructor(private dialog: MatDialog) {}
 
openPopup() {
    const dialogRef = this.dialog.open(PopupShellComponent, {
         data: { 
           component: UserPopupComponent,
           // 这里放所有要传给UserPopupComponent的参数
           componentData: {
             userId: 1001,
             userName: '测试用户',
             editMode: true
           }
         },
    });

    // 可订阅弹窗关闭事件拿子组件返回的结果
    dialogRef.afterClosed().subscribe(result => {
      console.log('弹窗返回结果', result);
    })
}

第四步:子组件中直接注入获取参数

在UserPopupComponent中注入POPUP_CHILD_DATA即可拿到传递的参数,注入MatDialogRef即可控制弹窗:

import { Component, Inject } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { POPUP_CHILD_DATA } from '../popup-tokens';

@Component({
  // 原有组件配置不变
  selector: 'app-user-popup',
  templateUrl: './user-popup.component.html'
})
export class UserPopupComponent {
  constructor(
    // 注入拿到父级传递的参数
    @Inject(POPUP_CHILD_DATA) public popupData: any,
    // 注入弹窗实例控制弹窗
    private dialogRef: MatDialogRef<PopupShellComponent>
  ) {}

  ngOnInit() {
    // 直接使用参数即可
    console.log('拿到的用户ID', this.popupData.userId);
    console.log('拿到的用户名', this.popupData.userName);
  }

  // 子组件主动关闭弹窗并返回结果
  close() {
    this.dialogRef.close({
      success: true,
      data: '子组件返回的结果'
    })
  }
}
注意事项
  • 如果你用的是Angular 14+的standalone组件,确保POPUP_CHILD_DATA和MatDialog相关依赖在子组件的imports或者providers里正确声明
  • Angular 9+之后使用ivy编译器,动态加载的组件不需要额外加到entryComponents里

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 18:06:03