Angular Material:如何在mat-stepper中传入预定义组件?
如何将预定义组件传入Mat-Stepper(不使用模板选择器)
要实现将未在模板中直接使用选择器的预定义组件传入Mat-Stepper,核心是利用Angular的动态组件加载能力,结合Mat-Stepper的步骤容器来挂载组件,具体步骤如下:
1. 配置预定义组件的模块声明
首先确保你的预定义组件在所属模块中正确注册,Angular 9+虽不再强制要求entryComponents,但为了兼容旧版本或明确声明,建议添加:
@NgModule({ declarations: [AppComponent, CustomStepComponent], entryComponents: [CustomStepComponent], // Angular 9+可省略,保留则兼容性更好 bootstrap: [AppComponent] }) export class AppModule { }
2. 在Mat-Stepper中设置动态挂载容器
在模板的mat-step内部,用ng-template标记一个用于挂载动态组件的容器,并通过模板引用变量获取它:
<mat-vertical-stepper> <mat-step label="自定义步骤"> <!-- 动态组件的挂载容器 --> <ng-template #stepHost></ng-template> </mat-step> </mat-vertical-stepper>
3. 编写动态加载组件的逻辑
在宿主组件类中,通过ViewContainerRef获取容器实例,然后创建并挂载预定义组件:
import { Component, ViewChild, ViewContainerRef, OnInit } from '@angular/core'; import { CustomStepComponent } from './custom-step.component'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { // 获取步骤容器的ViewContainerRef @ViewChild('stepHost', { read: ViewContainerRef }) stepHost!: ViewContainerRef; ngOnInit(): void { // 清空容器(避免重复加载) this.stepHost.clear(); // Angular 13+ 简化写法:直接传入组件类创建实例 const componentRef = this.stepHost.createComponent(CustomStepComponent); // 传递输入属性(如果有) // componentRef.instance.stepData = { id: 1, name: "自定义步骤" }; // 监听组件输出事件(如果有) // componentRef.instance.onComplete.subscribe(() => { /* 处理步骤完成逻辑 */ }); } }
如果你使用Angular 12及以下版本,需要注入
ComponentFactoryResolver来创建组件工厂:import { ComponentFactoryResolver } from '@angular/core'; constructor(private cfr: ComponentFactoryResolver) {} ngOnInit(): void { const factory = this.cfr.resolveComponentFactory(CustomStepComponent); this.stepHost.createComponent(factory); }
4. 多步骤动态加载扩展
如果需要给不同的mat-step加载不同的预定义组件,只需给每个步骤容器设置独立的模板引用变量,分别处理即可:
<mat-vertical-stepper> <mat-step label="步骤1"> <ng-template #step1Host></ng-template> </mat-step> <mat-step label="步骤2"> <ng-template #step2Host></ng-template> </mat-step> </mat-vertical-stepper>
@ViewChild('step1Host', { read: ViewContainerRef }) step1Host!: ViewContainerRef; @ViewChild('step2Host', { read: ViewContainerRef }) step2Host!: ViewContainerRef; ngOnInit(): void { this.step1Host.createComponent(Step1Component); this.step2Host.createComponent(Step2Component); }
注意事项
- 动态创建的组件实例需要在宿主组件销毁时清理,避免内存泄漏:可在
ngOnDestroy中调用componentRef.destroy()或stepHost.clear()。 - 组件的输入输出属性需通过
componentRef.instance直接访问,无法通过模板绑定的方式传递。
内容的提问来源于stack exchange,提问作者L. Kvri
相关产品推荐
相关产品推荐

