角料步进选择前更改并在某些情况下防止步进变化

时间:2019-04-03 14:39:22

标签: angular angular-cdk angular-material-7 angular-material-stepper

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

接下来可以正常工作。我会进行api调用,如果成功,则会调用stepper-next事件,而不是使用matStepperNext指令。

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

我想先进行服务呼叫,并且防止步进更改,直到服务呼叫成功,然后才应将其重定向到下一步,否则不应该。< / p>

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

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

5 个答案:

答案 0 :(得分:0)

您可以尝试利用editable上的completedmat-step属性。

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

没有看到一个示例,一种解决方法是:

  1. 在进行服务调用时将editable属性设置为所有其他步骤的false
  2. 将点击次数跟踪到mat-step并保持该值,以便您知道用户打算去的地方
  3. 在服务调用成功或失败时(取决于您要如何处理错误)将editable属性设置为true
  4. 以编程方式转到#2中跟踪的步骤

答案 1 :(得分:0)

我不确定这是否是最好的模式,但是它对我有用。欢迎提出建议。

1)使步进步进线性

<mat-vertical-stepper [linear]="true" #stepper>

  ....

</mat-vertical-stepper>

2)使步骤不可编辑,不是可选步骤,并将stepControl与FormGroup关联

  <mat-step [editable]="false" [optional]="false" [stepControl]="desiredServiceFormGroup">

    <form [formGroup]="desiredServiceFormGroup">

      ...

    </form>

  </mat-step>

3)为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是线性的,直接单击步骤标题不会更改当前步骤。

5)按钮将不会与formControl关联(在这种情况下,它将始终被禁用)。就我而言,我手动验证每个表单项

<button [disabled]="desiredTarget == null || !paymentAgreed" (click)="createVerification(desiredTarget.targetId, stepper)">NEXT</button>

6)进行所需的操作,并在操作完成后,删除使窗体控件始终无效的多余控件,然后以编程方式转到下一步。

async createVerification(targetId: number, stepper?: MatStepper) {

  this.verification = await this.dataService.createVerification(targetId);

  if (stepper !== undefined) {
    this.desiredServiceFormGroup.removeControl('x');
    stepper.next();
  }

}

7)如果您需要重置步进器,请记住将额外的控件添加到FormControl中

reset(stepper?: MatStepper) {
  this.desiredServiceFormGroup.addControl('x', new FormControl('', [Validators.required]));
  stepper.reset();
}

答案 2 :(得分:0)

这是根据我对蔡三杰的回答得出的一个可行建议。我只是使用一个“ step”值作为代码,并且仅使用普通按钮进行导航。

如果按钮正确,则只能前进和后退 (我的意思是,这无法通过单击步骤来更改步骤)。这意味着您先完成第一步,然后完成第二步,依此类推。

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

诀窍是调用goStep(x),其中x是从1开始的步骤。您可以通过添加一个简单的goNext()goPrevious()来增强这一功能。 / p>

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

答案 3 :(得分:0)

这里是您可以对此进行完全控制的方式。经验证,可以正常工作。对于"@angular/cdk": "8.2.3",我不确定将来的任何版本,也许他们对此具有一些内置功能。<​​/ p>

简短答案: 在页面上绘制步进器组件后。您应该循环浏览步进器的所有步骤,并使用自己的版本覆盖每个步骤的内置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;
        };
    });
});

答案 4 :(得分:-1)

您不必像下面这样使用^FB
 matStepperNext

但是相反,您可以使用自己的函数,如下所示:

<button mat-button matStepperNext>Next</button>

,然后在ts文件中获得步进器的实例,如下所示:
<button mat-button (click)="moveToNextStep()">Next</button>

那是在您在html中添加模板变量之后,如下所示:
@ViewChild('stepper') stepper: MatStepper;

然后您的<mat-horizontal-stepper [linear]="true" #stepper>应该如下所示:

moveToNextStep()

当然,您也可以像以前那样做:
 public moveToNextStep(): void { // Here make your api call and your form validation if ( your all is good move to next step) { this.stepper.next(); // <==== that's how you trigger moving to next step manually } else { //display some message to the user } }

<button mat-button (click)="moveToPreviousStep()">Previous</button>

使用标题标签:

如果您需要使用stepper标头在各个步骤之间切换,则可以使用public moveToPreviousStep(): void { this.stepper.previous(); } ,如下所示:
selectionChange

然后添加您的函数来处理调用api,验证表单以及是否移至下一步的功能;像这样的东西:

<mat-horizontal-stepper #stepper (selectionChange)="onStepChange(stepper.selectedIndex)">