角度7材料步进式反应形式复位不起作用

时间:2019-08-10 21:14:06

标签: angular

我将Angular Material与Angular 7一起使用。我有很多反应式,每个反应式都在自己的控件中,每个反应式都更新要编辑的主要对象的不同属性集合。这些控件分别位于Angular Material Stepper控件的不同步骤中。

每个控件都有一个名为“添加新”的按钮,它允许用户将新对象添加到集合中,还有一个“编辑”按钮来编辑集合中的任何现有项目。每当单击“添加新”按钮时,我都会创建一个具有默认值的新项目(大多数为空),并将其绑定到控件中的反应形式。

该表格始终允许用户单击“添加到收藏夹”按钮(即该按钮从不禁用),并且此时会向用户显示验证错误(如果有)。 (如果存在验证错误,则该项目不会添加到集合中。)

一切正常,直到我进入Stepper控件的另一步骤,然后返回正在执行的步骤。发生这种情况时,我单击“添加新”按钮,即使用户未单击“添加到收藏集”按钮,我也会立即看到所有必需的验证错误。当我查看控件的值时,我看不出任何应该显示验证错误的原因,但是它们却是错误的(在空的输入周围以红色突出显示)。

这是每当用户单击“添加新”时我正在运行的代码:

public resetForm(formGroup: FormGroup) {
if (!formGroup)
  return;

  formGroup.reset();
  formGroup.clearValidators();
  // see https://stackoverflow.com/questions/48216330/angular-5-formgroup-reset-doesnt-reset-validators
  Object.keys(formGroup.controls).forEach(key => {
    if (ignoreControls.indexOf(key) == -1) {
      formGroup.get(key).setErrors(null);
      formGroup.get(key).markAsPristine();
      formGroup.get(key).markAsUntouched();
      formGroup.get(key).clearValidators();
      formGroup.get(key).updateValueAndValidity();
    }
  }); 

当我查看单个控件时,在html中,我看到了所有希望看到的内容:

<input _ngcontent-wyd-c14="" class="mat-input-element mat-form-field-autofill-control cdk-text-field-autofill-monitored ng-untouched ng-pristine ng-invalid" formcontrolname="title" matinput="" placeholder="e.g. Customer Service Representative" required="" type="text" ng-reflect-required="" ng-reflect-name="title" ng-reflect-placeholder="e.g. Customer Service Represen" ng-reflect-type="text" id="mat-input-24" aria-invalid="true" aria-required="true">

请注意,该类包含ng-touched和ng-pristine(以及ng-invalid)。如果某个字段是原始且未修改的,则不应显示验证错误。

我怀疑是在Stepper控件上更改为其他步骤会导致某种形式的表单提交或提交尝试,这就是为什么所有错误都会显示出来(form.submitted == true或类似的东西)的原因。但是我不知道如何重设任何内容以将其视为全新的表单。

有人可以帮忙吗?

(注意:我看过很多SO文章,建议我需要在form指令上调用resetForm,而不是formGroup(例如,Angular 5 FormGroup reset doesn't reset validators)。 但是,当我在表单标签中添加#formDirective =“ ngForm”并添加到我的打字稿中时:

@ViewChild('formDirective') private formDirective: NgForm;

然后我将其称为this.formDirective.resetForm(),这没有什么不同-验证错误仍会立即显示。

更新:这是一个基本显示问题的堆栈闪电战。从第一步单击“保存并继续”,然后在第二步单击“添加”。表格显示没有验证错误。现在,单击步进器的“简介”步骤,然后单击回到“体验”步骤,当您返回到该步骤时,您将看到所有验证均出现。这是我实际的生产项目中的问题-用户应该能够在不触发验证的情况下从一个步骤导航到另一步骤。在体验组件中,您可以看到每次调用intiForm方法时都试图重置表单,但是您仍然看到错误。为什么?链接:https://stackblitz.com/edit/angular-w4iunu

1 个答案:

答案 0 :(得分:1)

  

我怀疑是在步进器上更改为其他步骤   控制导致某种形式的表单提交或提交尝试,并且   这就是为什么所有错误都显示出来的原因(form.submitted == true或其他原因   这样)。

您在这里。单击“添加新”按钮将导致提交表单,因为任何button in HTML by default的类型均为submit。单击Add New按钮后,您的表单将获得submitted标志。

解决方案应该很简单:

 <button mat-raised-button color="primary" (click)="addNew()" type="button"...>Add New</button>
                                                               ^^^^^^^^^
                                                              add this

Forked Stackblitz

这里的另一个问题是,步进器在计算控制的错误状态时会考虑步进的interacted属性。一旦从一个步骤移至另一步骤,它将变为true

您可以通过在selectionChange上重置此属性来解决此问题:

app.component.html

<mat-horizontal-stepper #diaryStepper ... (selectionChange)="stepIndexChanged(diaryStepper)"

app.component.ts

stepIndexChanged(stepper) {
  stepper.steps.toArray().forEach(step => step.interacted = false)
}

Updated Stackblitz