8

我正在使用线性垫步进器。

它适用于下一个。我做 api 调用 & 如果它成功然后我调用 stepper-next 事件而不是使用 matStepperNext 指令。

现在,当用户在第 1 步填写所有数据并直接单击下一步标题 r 中的其他步骤(或任何其他编辑记录模式)时,由于表单有效,它将重定向到下一步。

我想在此之前进行服务调用防止步骤更改,直到服务调用成功然后它才应该重定向到下一步,否则它不应该。

我在文档中找不到任何实现此功能的方法。

谁能建议我该怎么做。我不想禁用标题点击。

4

5 回答 5

4

以下方法对我有用:

  1. 使 mat-stepper 线性化
<mat-vertical-stepper [linear]="true" #stepper>

  ....

</mat-vertical-stepper>
  1. 使步骤不可编辑,不是可选的,并将 stepControl 与 FormGroup 关联
<mat-step [editable]="false" [optional]="false" [stepControl]="desiredServiceFormGroup">
  
    <form [formGroup]="desiredServiceFormGroup">
  
      ...
  
    </form>
  
</mat-step>
  1. 为您在 HTML 中描述的表单项添加控件到您的 FormGroup 并添加一个额外的控件。对于您的 html 代码中不存在的表单控件(在此示例中,我添加了名为“x”的控件,在我的 html 代码中不存在)
ngOnInit() {
  
  this.desiredServiceFormGroup = this.formBuilder.group({
    desiredTarget: [ '', Validators.required],
    paymentAgreed: ['', Validators.required],

    ...

    x: ['', Validators.required]
  });
  
}

使用这个额外的验证器,您的 stepControl 将始终为 false。当 stepControl 为 false 时,step 不是可选的,不可编辑且 stepper 是线性的。直接单击步骤标题不会更改当前步骤。

  1. 按钮不会与 formControl 关联(在这种情况下,它将始终被禁用)。就我而言,我手动验证每个表单项
<button [disabled]="desiredTarget == null || !paymentAgreed" (click)="createVerification(desiredTarget.targetId, stepper)">NEXT</button>
  1. 进行所需的操作,完成后,删除使表单控件始终无效的额外控件。以编程方式进行下一步。
async createVerification(targetId: number, stepper?: MatStepper) {
  
  this.verification = await this.dataService.createVerification(targetId);
  
  if (stepper !== undefined) {
    this.desiredServiceFormGroup.removeControl('x');
    stepper.next();
  }
  
}
  1. 如果您需要重置步进器,请将额外的控件添加到 FormControl
reset(stepper?: MatStepper) {
  this.desiredServiceFormGroup.addControl('x', new FormControl('', [Validators.required]));
  stepper.reset();
}
于 2019-12-19T06:00:28.820 回答
2

这是您可以完全控制的方法。证明,工作。对于"@angular/cdk": "8.2.3",我不确定任何未来的版本,也许他们有一些内置的功能。

简短回答: 在页面上呈现步进器组件后。您应该遍历步进器的所有步骤,并用您自己的版本覆盖每个步骤的内置select()方法。

你会在自己的版本中做什么?

  • 做一些计算
  • 拨打服务电话
  • 无论你想要什么
  • currentStepIndex如果您希望用户进入新步骤,请更改

长答案:

HTML:

<mat-horizontal-stepper [selectedIndex]="selectedStepIndex" #stepper>

在控制器中:

@ViewChild('stepper', { static: false }) stepper: MatStepper;

在页面上呈现步进器后,您可以覆盖select如下方法:

// I personally do this in ngAfterViewInit() method
setTimeout(() => {
    this.stepper.steps.forEach((step, idx) => {
        step.select = () => {
            // Your custom code here
            // if you want to change step do execute code below
            this.selectedStepIndex = idx;
        };
    });
});
于 2020-07-08T03:56:40.113 回答
1

这是一个基于 Sam Tsai 答案的工作建议,这是我发现的最好的。我只是使用“step”值是代码,并且只有普通的导航按钮。

只有当您拥有正确的按钮时,您才能返回和前进(我的意思是,这不可能通过单击步骤来更改步骤)。这意味着您完成了第一步,然后完成了第二步,依此类推。

工作示例在这里: https ://stackblitz.com/edit/angular-tznwxe

诀窍是调用goStep(x)where是从 1 开始的步骤。您可以通过添加 a和 ax来增强这一点,这很简单。goNext()goPrevious()

请注意,步进器的“selectedIndex”必须更改为setTimeout():这是此处讨论的已知错误:https ://github.com/angular/components/issues/8479#issuecomment-444063732

于 2020-04-29T16:12:54.917 回答
0

editable您可以尝试completedmat-step.

https://material.angular.io/components/stepper/overview#editable-step

在没有看到示例的情况下,一种解决方案是:

  1. 在进行服务调用时将所有其他步骤的editable属性设置为false
  2. 跟踪点击mat-step并保留此值,以便您知道用户打算去哪里
  3. editable属性设置为true服务调用成功或失败的时间(取决于您希望如何处理错误)
  4. 以编程方式转到 #2 中跟踪的步骤
于 2019-04-09T20:29:22.233 回答
0

您可以使用完成的输入装饰(布尔值),如果步骤1被标记为完成,那么它将转到步骤2。

一旦您的服务调用完成,您可以将完成标记为“true”,然后它将转到第 2 步,否则它将停留在当前步骤。

参考:https ://stackblitz.com/edit/angular-mat-stepper-demo-with-selection-change?file=src%2Fapp%2Fapp.component.html

于 2021-11-23T05:15:12.327 回答