基于Material Dialog与响应式表单构建动态可复用自动化助手步骤器
Angular 动态步骤复用组件实现方案
核心思路
通过TemplateRef结合ngTemplateOutlet实现步骤内容的动态注入,搭配可配置的步骤数组,适配不同用户类型的多流程(3步/5步注册等)复用需求。
实现步骤
1. 定义步骤配置接口
创建统一的步骤配置结构,包含步骤标题和内容模板引用:
import { TemplateRef } from '@angular/core'; export interface StepConfig { title: string; contentTemplate: TemplateRef<any>; // 可扩展:添加disabled、completed等状态字段 }
2. 封装通用步骤组件
构建可复用的步进器组件,接收步骤配置数组并动态渲染内容:
import { Component, Input, Output, EventEmitter } from '@angular/core'; import { StepConfig } from './step-config.interface'; @Component({ selector: 'app-reusable-stepper', template: ` <mat-stepper linear> <mat-step *ngFor="let step of steps; let i = index" [label]="step.title" [completed]="step.completed" [disabled]="step.disabled" > <ng-container [ngTemplateOutlet]="step.contentTemplate"></ng-container> <div> <button mat-button (click)="onNext(i)" *ngIf="i < steps.length - 1">下一步</button> <button mat-button (click)="onPrev(i)" *ngIf="i > 0">上一步</button> <button mat-button (click)="onFinish()" *ngIf="i === steps.length - 1">完成</button> </div> </mat-step> </mat-stepper> ` }) export class ReusableStepperComponent { @Input() steps: StepConfig[] = []; @Output() next = new EventEmitter<number>(); @Output() prev = new EventEmitter<number>(); @Output() finish = new EventEmitter<void>(); onNext(index: number) { this.next.emit(index); } onPrev(index: number) { this.prev.emit(index); } onFinish() { this.finish.emit(); } }
注:示例使用Angular Material步进器,可替换为自定义步进器结构。
3. 父组件中配置并传入模板
在业务组件中定义各步骤的内容模板,根据业务逻辑动态组装步骤数组:
import { Component, ViewChild, TemplateRef, OnInit } from '@angular/core'; import { StepConfig } from './step-config.interface'; @Component({ selector: 'app-root', template: ` <app-reusable-stepper [steps]="currentSteps" (next)="handleNext($event)" (prev)="handlePrev($event)" (finish)="handleFinish()" ></app-reusable-stepper> <!-- 步骤1模板:基础信息 --> <ng-template #basicInfoTpl> <div class="step-content"> <h4>基础信息填写</h4> <mat-form-field> <input matInput placeholder="用户名" required> </mat-form-field> <mat-form-field> <input matInput placeholder="邮箱" required> </mat-form-field> </div> </ng-template> <!-- 步骤2模板:身份验证 --> <ng-template #authTpl> <div class="step-content"> <h4>身份验证</h4> <mat-form-field> <input matInput placeholder="验证码" required> </mat-form-field> <button mat-button>发送验证码</button> </div> </ng-template> <!-- 步骤3模板:密码设置 --> <ng-template #pwdSetTpl> <div class="step-content"> <h4>设置登录密码</h4> <mat-form-field> <input matInput type="password" placeholder="密码" required> </mat-form-field> </div> </ng-template> <!-- VIP专属步骤模板 --> <ng-template #vipConfigTpl> <div class="step-content"> <h4>VIP专属配置</h4> <mat-checkbox>开启专属客服通道</mat-checkbox> </div> </ng-template> ` }) export class AppComponent implements OnInit { @ViewChild('basicInfoTpl') basicInfoTpl!: TemplateRef<any>; @ViewChild('authTpl') authTpl!: TemplateRef<any>; @ViewChild('pwdSetTpl') pwdSetTpl!: TemplateRef<any>; @ViewChild('vipConfigTpl') vipConfigTpl!: TemplateRef<any>; currentSteps: StepConfig[] = []; isVipUser = true; // 模拟VIP用户判断 ngOnInit() { // 基础步骤数组 this.currentSteps = [ { title: '基础信息', contentTemplate: this.basicInfoTpl, completed: false, disabled: false }, { title: '身份验证', contentTemplate: this.authTpl, completed: false, disabled: true }, { title: '密码设置', contentTemplate: this.pwdSetTpl, completed: false, disabled: true } ]; // 根据用户类型添加额外步骤 if (this.isVipUser) { this.currentSteps.push({ title: 'VIP配置', contentTemplate: this.vipConfigTpl, completed: false, disabled: true }); } } handleNext(index: number) { // 标记当前步骤为完成,启用下一步 this.currentSteps[index].completed = true; if (index + 1 < this.currentSteps.length) { this.currentSteps[index + 1].disabled = false; } } handlePrev(index: number) { // 回退时禁用当前步骤,取消上一步完成状态 this.currentSteps[index].disabled = true; this.currentSteps[index - 1].completed = false; } handleFinish() { console.log('流程完成'); // 后续业务逻辑:提交表单、跳转页面等 } }
4. 常见失败原因排查
- 模板引用时机错误:必须在
ngAfterViewInit或ngOnInit(配合static: false)中获取TemplateRef,视图未初始化时无法获取实例 - 模板标记重复:确保
#xxxTpl的命名全局唯一,避免@ViewChild匹配错误 ngTemplateOutlet绑定错误:需直接绑定TemplateRef实例,而非字符串或其他类型
内容的提问来源于stack exchange,提问作者PKHDK
相关产品推荐
相关产品推荐

