Mat Stepper满足支付成功条件时无法跳转至下一步的问题
解决Mat Horizontal Stepper支付成功后无法跳转的问题
问题场景
使用Angular Material的mat-horizontal-stepper组件,嵌套了组件A和组件B。需求是点击组件A的支付按钮后,若支付成功(条件C)自动跳转到组件B所在的第二步;支付失败则停留在第一步。但目前支付成功后无法完成跳转。
原代码展示
组件A的TS文件
@ViewChild(MatStepper) stepper!: MatStepper; pay() { if(payment === "success"){ this.goToNextStep() } else{ console.warn("error") } goToNextStep() { console.log('Going to the next step...'); if (this.stepper) { this.stepper.next(); } }
组件A的HTML文件
<button (click)="pay()"> go to step 2 when payment is successful <button>
步进器的HTML文件
<mat-horizontal-stepper #stepper [linear]="true"> <mat-step> <app-component-a></app-component-a> </mat-step> <mat-step> <app-component-b></app-component-b> </mat-step> </mat-horizontal-stepper>
组件B的HTML文件
payment successful
问题原因
组件A中通过@ViewChild(MatStepper)获取步进器实例的方式无效,因为@ViewChild只能查询当前组件模板范围内的元素。而mat-horizontal-stepper是在组件A的父组件模板中,所以this.stepper会是undefined,调用stepper.next()自然没有反应。
解决方案
提供两种可行的解决方式:
方式一:通过@Input传递步进器实例
- 修改组件A的TS代码,添加
@Input属性接收父组件传递的步进器:
import { Component, Input } from '@angular/core'; import { MatStepper } from '@angular/material/stepper'; @Component({ selector: 'app-component-a', templateUrl: './component-a.component.html' }) export class ComponentAComponent { @Input() stepper!: MatStepper; pay() { // 替换为实际支付逻辑判断结果 const payment = "success"; if(payment === "success"){ this.goToNextStep(); } else { console.warn("支付失败"); } } goToNextStep() { console.log('准备跳转到下一步...'); if (this.stepper) { // 线性步进器需标记当前步骤为完成 this.stepper.selected!.completed = true; this.stepper.next(); } } }
- 修改步进器的HTML文件,将
#stepper传递给组件A:
<mat-horizontal-stepper #stepper [linear]="true"> <mat-step> <app-component-a [stepper]="stepper"></app-component-a> </mat-step> <mat-step> <app-component-b></app-component-b> </mat-step> </mat-horizontal-stepper>
方式二:通过@Output事件通知父组件跳转
- 修改组件A的TS代码,添加
@Output事件触发支付成功的通知:
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-component-a', templateUrl: './component-a.component.html' }) export class ComponentAComponent { @Output() paymentSuccess = new EventEmitter<void>(); pay() { const payment = "success"; if(payment === "success"){ this.paymentSuccess.emit(); } else { console.warn("支付失败"); } } }
- 修改步进器的HTML文件,监听组件A的事件并执行跳转:
<mat-horizontal-stepper #stepper [linear]="true"> <mat-step> <app-component-a (paymentSuccess)="stepper.selected!.completed = true; stepper.next()"></app-component-a> </mat-step> <mat-step> <app-component-b></app-component-b> </mat-step> </mat-horizontal-stepper>
注意事项
因为启用了[linear]="true"线性步进模式,必须确保当前步骤标记为completed,否则无法跳转。两种方案中都处理了这个逻辑,可保证跳转正常执行。
内容的提问来源于stack exchange,提问作者Luigi Woodhouse
相关产品推荐
相关产品推荐

