如何验证具有嵌套表单组的反应式表单? [英] How to validate reactive forms with nested form groups?

查看:0
本文介绍了如何验证具有嵌套表单组的反应式表单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个嵌套的表单组,如https://plnkr.co/edit/c93yFe2r83cvjiRvl6Uj?p=preview所示。

这是https://angular.io/docs/ts/latest/cookbook/form-validation.html#!#reactive

中的示例分叉

该示例以角度显示,当表单没有任何嵌套组时使用validationMessages。当我有嵌套的表单组时,我不确定如何扩展它。以下是我要创建的示例表单和验证消息。

  buildForm(): void {
    this.heroForm = this.fb.group({
      'name': [this.hero.name, [
          Validators.required,
          Validators.minLength(4),
          Validators.maxLength(24),
          forbiddenNameValidator(/bob/i)
        ]
      ],
      'address': this.fb.group({
        'city': [''],
        'state': ['']
      }),
      'alterEgo': [this.hero.alterEgo],
      'power':    [this.hero.power, Validators.required]
    });

    this.heroForm.valueChanges
      .subscribe(data => this.onValueChanged(data));

    this.onValueChanged(); // (re)set validation messages now
  }

预期formErrorsvalidationMessages

  formErrors = {
    'name': '',
    'power': '',
    'address': {
      'state': '',
      'city': ''
    }
  };

  validationMessages = {
    'name': {
      'required':      'Name is required.',
      'minlength':     'Name must be at least 4 characters long.',
      'maxlength':     'Name cannot be more than 24 characters long.',
      'forbiddenName': 'Someone named "Bob" cannot be a hero.'
    },
    'power': {
      'required': 'Power is required.'
    },
    'address': {
      'city': {
        'required':      'City is required.',
        'minlength':     'City must be at least 4 characters long.',
      },
      'state': {
        'required':      'State is required.',
        'minlength':     'State must be at least 4 characters long.',
      }
    }
  };

以下是onValueChanged

  onValueChanged(data?: any) {
    if (!this.heroForm) { return; }
    const form = this.heroForm;

    for (const field in this.formErrors) {
      // clear previous error message (if any)
      this.formErrors[field] = '';
      const control = form.get(field);

      if (control && control.dirty && !control.valid) {
        const messages = this.validationMessages[field];
        for (const key in control.errors) {
          this.formErrors[field] += messages[key] + ' ';
        }
      }
    }
  }

如何更新上述onValueChanged函数以支持嵌套表单组验证?

我之所以执行上面的操作,是因为我有一个向导表单,并且我想在进入向导的下一步之前验证嵌套的表单组。每个向导步骤都包含一个嵌套的表单组。在转到下一步之前,当前向导步骤必须有效。我不想将向导的内容放到多个组件中,因为来自向导的所有数据必须在结束时一起提交给远程服务。因此,我看不出拥有多个组件的复杂性有什么价值。

推荐答案

我知道这是一个古老的故事,但我试图同步获取validateAllFormGroups(formGroup: FormGroup),但我在某个地方找不到任何答案,因此我实现了我的方法:

function validateAllFormGroups(formGroup: FormGroup): boolean {
    let hasErrors = false;

    Object.keys(formGroup.controls).forEach((field) => {
      const control = formGroup.get(field);

      hasErrors =
        control instanceof FormGroup
          ? hasErrors || !validateAllFormGroups(control)
          : hasErrors || !!control?.errors;
    });

    return !hasErrors;
}

您可以调整它以获得应用程序逻辑所需的结果,对我来说,布尔值就足够了。

欢迎任何优化或建议

这篇关于如何验证具有嵌套表单组的反应式表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆