【问题标题】:Adding custom validator to whole form group in Angular Reactive From在Angular Reactive From中将自定义验证器添加到整个表单组
【发布时间】:2019-11-21 13:09:24
【问题描述】:

我基于从 API 接收的 JSON 数据在 Angular 中动态创建响应式表单。有时表单只有几个formControls,但有时有很多表单组或带有FormGroups的formArrays。

我对带有多个 FormGroup 的 FormArray 有疑问。在这个 FormGroups 中,一些 FormControls 可能是必需的,而有些则不是。但不需要整个 FormGroup。只有在组中的某些 FormControl 被编辑后,整个表单组必须有效(每个所需的 FormControl 不能为空)。

所以我的问题是如何为整个 FormGroup 创建自定义验证器,这将确保如果这些具体组中的每个 FormControl 都为空,那么该组将是有效的。但是,例如,如果要编辑一个 FormControl,则必须填写每个所需的 FormControl。

非常感谢您的想法。

【问题讨论】:

  • 请添加您的代码。
  • 我的解决方案的代码非常广泛,出于安全原因我无法共享它。我的问题只是关于自定义通用验证器,它将像我在我的问题中写的那样工作。对不起。
  • 仅供参考,将来,如果您由于某种原因无法添加您的确切代码,您应该创建一个简化版本来演示您的问题。

标签: angular forms validation


【解决方案1】:

试试这个简单的解决方案怎么样

这是我的表单初始化

this.sponsorshipForm = this.fb.group(
  {
    startDate: ['', [Validators.required]],
    endDate: ['', [Validators.required]]
  },
  { validators: [this.sponsorshipDurationValidation] }
);

这是我的验证器,你可以制作任何你需要的东西并自定义它

sponsorshipDurationValidation(form: FormGroup) {
   if (form.value.startDate && form.value.end) {
     console.log('form ', form, form.status);
   }
   if (something false happen or not valid value) {
     return { validUrl: true };
  }
  return null;
}

【讨论】:

    【解决方案2】:

    您可以使用 FormBuilder 服务添加这样的表单组级别验证器:

    this.myFormGroup = this.formBuilder.group({ 
                         ... my group info ... 
                       }, {validators: [... validators ... ]);
    

    自定义验证器的行为与任何其他的一样,但在这种情况下,抽象控件是一个 FormGroup,可以像任何其他表单组一样对待。

    类似:

    function allOrNoneRequired(): ValidatorFn {
      return (ctrl: AbstractControl): ValidationErrors | null => {
        const fg = ctrl as FormGroup;
        const controls = Object.values(fg.controls);
        return (controls.every(fc => !fc.value) || controls.every(fc => !!fc.value))  
                 ? null 
                 : {allOrNoneRequired: true};
      };
    }
    

    然后

    this.myFormGroup = this.formBuilder.group({ 
                         ... my group info ... 
                       }, {validators: [allOrNoneRequired()]);
    

    【讨论】:

    • 我已尝试过此解决方案,但出现错误“无法调用类型缺少调用签名的表达式。类型‘AbstractControl’没有兼容的调用签名。”符合return语句。我不知道为什么。
    • 我做了一些修改,原版有错误,请确保您拥有最新版本,这是经过测试的
    猜你喜欢
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多