【问题标题】:Using the ChangeDetectorRef to detect component state changes in order to step with the material stepper?使用 ChangeDetectorRef 检测组件状态变化以便与材料步进器一起步进?
【发布时间】:2019-08-18 03:06:43
【问题描述】:

在 Angular 8 Material Stepper 中,我正在检查一些表单状态,如果它通过了,那么我将 stepCompleted 设置为 true。

这是一个演示此功能的 Stackblitz: https://stackblitz.com/edit/angular-mat-stepper-demo-with-fields?file=src%2Fapp%2Fapp.component.html

问题是 Angular 没有立即接受更改,因此我们必须单击“下一步”两次。第二次点击会看到状态变化。

此外,如果我们导航回该步骤并更改参数以使该步骤不应继续,Angular 仍将允许该步骤在第一次单击时继续,因为它仍然认为stepCompleted 为真。在我们再次导航之前,这不是错误的。

我认为解决这个问题的正确方法是注入 ChangeDetectorRef 并像这样调用它:

stepComplete() {
   //See whether the step is complete
   //if so
   this.stepCompleted = true;
   this.cd.detectChanges();
}

想法?

【问题讨论】:

  • 可能是更好的方法。使用变更检测器通常很麻烦,与设置超时或解决强制变更检测的承诺相当。在没有看到更多设置的情况下无法说出真正的问题是什么
  • 从这篇文章中得到了 ChangeDetectorRef 的想法:alligator.io/angular/stripe-elements
  • 这是一个类似的概念。在这种情况下,如果出现错误,则需要手动触发更改检测,以便表单显示错误。
  • 我的意思是这是一个奇怪的案例,因为他们使用了一个没有真正集成到 Angular 中的 3rd 方库。所以这些函数是在 ngZone 之外调用的,所以变化检测不会像它应该触发的那样触发。他们实际上可以使用 ngZone 或 renderer2 更好地实现这种方式。您是否正在集成第三个招架库或其他东西?
  • 不只是使用角度材料步进器。单击下一步时,它会触发将stepComplete 设置为true 的函数,但前提是满足特定条件。但是 Angular 确实意识到 stepComplete 在第一次单击时已设置为 true。第二次点击就实现了。

标签: javascript angular typescript angular-material


【解决方案1】:

这里的问题是 button[matStepperNext] triggers navigation 在设置 completed 属性之前。

解决方案可以使用mousedown|touchstart 事件而不是click:

<button mat-button matStepperNext (mousedown)="toggleStep1Complete()">

Forked Stackblitz

另一个想法是不要使用button[matStepperNext]指令并手动触发导航:

<mat-horizontal-stepper linear #stepper>
  <mat-step label="Step 1">
    ...
    <button mat-button (click)="stepper.selected.completed = true; stepper.next()">Next</button>

Stackblitz Example

另见:

【讨论】:

  • 很好的答案!非常感谢!
  • @Ole 这里的另一个选项是将完成的属性设置为某种吸气剂。像get stepCompleted() { return this.stepForm.valid; } 这样可以保证变更检测的顺序。
猜你喜欢
  • 2018-04-13
  • 2016-01-25
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
  • 2021-09-04
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
相关资源
最近更新 更多