Angular2 FormGroup验证 - 标记特定控件无效

时间:2017-05-09 16:12:23

标签: angular angular2-forms angular-reactive-forms

我使用FormGroup有一个Angular 2 Reactive表单。我需要比较两个字段的值,所以我在创建时将验证器传递给FormGroup。验证效果很好:

this.form = this.formBuilder.group({
  add: this.formBuilder.group({
    mobile: ['', [
      Validators.required,
      this.duplicate
    ]],
    voice: [false]
  }),
  existing: this.formBuilder.array([])
}, {validator: this.validateDuplicates});

validateDuplicates(group: FormGroup): any {
  let adding = group.get('add').get('mobile').value;
  if (!adding) {
    return null;
  }

  let matches: boolean[] = (group.get('existing') as FormArray).controls
    .map(control => {
      return control.get('number').value;
    })
    .filter(val => val === adding);

  return matches.length > 0 ? {
    duplicate: {adding}
  } : null;
}

输入无效值后,将正确填充form.errors.duplicate字段,并在DOM中使用ng-invalid CSS类标记表单组。

我唯一的缺点是,当这个组级验证器失败时,我希望将特定的表单控件标记为ng-invalid。有没有办法做到这一点?我试过弄乱验证器函数返回的对象来匹配目标表单控件的嵌套层,但没有用。

在短期内,我可以通过在表单无效时在特定元素上添加额外的标记和样式来解决它,但理想情况下我希望能够摆脱它,并解决特定的错误代码仅在该控件的标记中,而不是上升到父窗体组级别:

<md-input-container class="primary" floatPlaceholder="never">
    <input mdInput name="mobile" type="text" pattern="^\([0-9]{3}\)\s[0-9]{3}\-[0-9]{4}$" placeholder="Number" formControlName="mobile" required>
    <md-hint *ngIf="!addControl.touched &amp;&amp; addControl.invalid" align="start" color="warn">(202) 555-5555</md-hint>
    <md-hint *ngIf="addControl.touched &amp;&amp; addControl.invalid" align="end" color="warn">Format must be (###) ###-####</md-hint>
    <!-- Workaround I'd like to remove -->
    <md-hint *ngIf="form.errors &amp;&amp; form.errors.duplicate">Numbers must be unique</md-hint>
</md-input-container>

1 个答案:

答案 0 :(得分:1)

要将特定控件标记为无效并将其指定为您选择的任意错误,您可以在您选择的控件上使用setErrrors方法。这也设置了父控件/组的有效性。

例如,在确定包含[a]重复值[s]的故障控件[s]之后,您可以在自定义验证器方法中执行此操作:

faultyCtrl.setErrors({duplicate: true});

请勿忘记从自定义验证程序返回错误,以便在组中正确设置errors属性,因为setErrors仅设置status属性,而不是{{1} (有关详细信息,请参阅this