如何在Angular mat stepper中修改已完成步骤后禁用后续剩余步骤
实现方案
完全可以通过 Angular Material 原生的 mat-stepper 属性实现该需求,无需额外依赖。
核心思路
利用mat-step自带的completed、editable属性,结合linear模式的规则,监听指定步骤的表单变更,动态重置后续步骤的完成状态即可:
linear模式保证用户必须按顺序完成步骤,未完成的步骤无法通过标签点击进入- 每个步骤单独绑定
completed状态,手动控制步骤是否标记为已完成 - 监听步骤2的表单值变化,只要用户修改了已完成的步骤2,直接将步骤3、4的
completed状态重置为false
核心代码示例
组件类代码
import { Component, ViewChild, OnInit, OnDestroy } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; import { MatStepper } from '@angular/material/stepper'; import { Subject, takeUntil, filter } from 'rxjs'; @Component({ selector: 'app-stepper-demo', templateUrl: './stepper-demo.component.html', styleUrls: ['./stepper-demo.component.scss'] }) export class StepperDemoComponent implements OnInit, OnDestroy { @ViewChild('stepper') stepper!: MatStepper; isLinear = true; // 各步骤表单 step1Form: FormGroup; step2Form: FormGroup; step3Form: FormGroup; step4Form: FormGroup; // 各步骤完成状态 step1Completed = false; step2Completed = false; step3Completed = false; step4Completed = false; private destroy$ = new Subject<void>(); constructor(private fb: FormBuilder) { this.step1Form = this.fb.group({ // 步骤1表单控件定义 }); this.step2Form = this.fb.group({ // 步骤2表单控件定义 }); this.step3Form = this.fb.group({ // 步骤3表单控件定义 }); this.step4Form = this.fb.group({ // 步骤4表单控件定义 }); } ngOnInit(): void { // 监听步骤2表单变更,已完成状态下修改则重置后续步骤 this.step2Form.valueChanges .pipe( filter(() => this.step2Completed), takeUntil(this.destroy$) ) .subscribe(() => { this.step3Completed = false; this.step4Completed = false; // 可选:清空后续步骤表单原有内容 this.step3Form.reset(); this.step4Form.reset(); }); } // 步骤提交逻辑 submitStep1() { if (this.step1Form.valid) { this.step1Completed = true; this.stepper.next(); } } submitStep2() { if (this.step2Form.valid) { this.step2Completed = true; this.stepper.next(); } } submitStep3() { if (this.step3Form.valid) { this.step3Completed = true; this.stepper.next(); } } submitStep4() { if (this.step4Form.valid) { this.step4Completed = true; // 全部完成后的业务逻辑 } } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }
模板代码
<mat-stepper [linear]="isLinear" #stepper> <mat-step [completed]="step1Completed" [editable]="step1Completed"> <ng-template matStepLabel>步骤1</ng-template> <!-- 步骤1表单内容 --> <button mat-button (click)="submitStep1()">下一步</button> </mat-step> <mat-step [completed]="step2Completed" [editable]="step2Completed"> <ng-template matStepLabel>步骤2</ng-template> <!-- 步骤2表单内容 --> <button mat-button (click)="stepper.previous()">上一步</button> <button mat-button (click)="submitStep2()">下一步</button> </mat-step> <mat-step [completed]="step3Completed" [editable]="step3Completed"> <ng-template matStepLabel>步骤3</ng-template> <!-- 步骤3表单内容 --> <button mat-button (click)="stepper.previous()">上一步</button> <button mat-button (click)="submitStep3()">下一步</button> </mat-step> <mat-step [completed]="step4Completed" [editable]="step4Completed"> <ng-template matStepLabel>步骤4</ng-template> <!-- 步骤4表单内容 --> <button mat-button (click)="stepper.previous()">上一步</button> <button mat-button (click)="submitStep4()">提交</button> </mat-step> </mat-stepper>
逻辑说明
当用户完成全部4个步骤后返回步骤2修改内容时,step2Form的值变化事件会触发,将步骤3、4的完成状态重置为false,此时linear模式会自动判定这两个步骤为未完成,禁止用户通过标签点击跳转,用户必须重新提交步骤2的表单后才能进入步骤3,依次完成后续流程,完全符合业务需求。
内容的提问来源于stack exchange,提问作者ani
相关产品推荐
相关产品推荐

