角形材料步进器在选择更改之前并防止某些条件下的步进变化

Ank*_*iya 6 angular angular-material-stepper angular-cdk angular-material-7

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

它与 next 一起工作正常。我进行 api 调用,如果成功,则调用 stepper-next 事件而不是使用 matStepperNext 指令。

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

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

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

任何人都可以建议我该怎么做。我不想禁用标题单击。

小智 5

以下方法对我有用:

  1. 使垫子步进器呈线性
<mat-vertical-stepper [linear]="true" #stepper>

  ....

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

    ...

    x: ['', Validators.required]
  });
  
}
Run Code Online (Sandbox Code Playgroud)

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

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


Pav*_*nko 5

您可以通过以下方法完全控制这一点。经证实,有效。对于"@angular/cdk": "8.2.3",我不确定未来的版本,也许他们有一些内置的功能。

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

您将在自己的版本中做什么?

  • 做一些计算
  • 拨打服务电话
  • 任何你想要的
  • currentStepIndex如果您希望用户转到新步骤,请更改

长答案:

HTML:

<mat-horizontal-stepper [selectedIndex]="selectedStepIndex" #stepper>
Run Code Online (Sandbox Code Playgroud)

在控制器中:

@ViewChild('stepper', { static: false }) stepper: MatStepper;
Run Code Online (Sandbox Code Playgroud)

一旦您的步进器呈现在页面上,您就可以重写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;
        };
    });
});
Run Code Online (Sandbox Code Playgroud)


Sam*_*sai 0

您可以尝试利用editablecompleted属性mat-step

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

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

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