Angular 反应式表单自定义验证器。仅在选中复选框时启用验证

Posted

技术标签:

【中文标题】Angular 反应式表单自定义验证器。仅在选中复选框时启用验证【英文标题】:Angular reactive forms custom validator. Enable Validation only when checkbox checked 【发布时间】:2019-02-21 10:27:50 【问题描述】:

我在验证仅标记的复选框时遇到问题。首先,当组件初始化并且所有复选框都被禁用时,如果他们单击保存按钮,它应该输出一个验证,表明您没有单击任何复选框。第二次验证是当您标记了一个复选框但您没有输入任何数量时,它应该只标记“此字段是必需的”。但是,现在,当我单击保存按钮时,即使禁用了所有数量,也会出现错误“此字段为必填项”。我该如何解决这个问题?还请我评论的功能,也许这会有所帮助。谢谢。

请点击这里查看我的 stackblitz 链接:CODE LINK

patchValues() 
    let rows = this.myForm.get('rows') as FormArray;
    this.orders.forEach(material => 
      material.materials.forEach(x => 
        rows.push(this.fb.group(
          checkbox_value: [null],
          material_id: new FormControl( value: x.id, disabled: true , Validators.required),
          material_name: x.name,
          quantity: [null]
        ));
        // this.formArrayLength++;
      );
    );
  

【问题讨论】:

【参考方案1】:

您需要为您的表单和数组中的子表单创建custom validators。

当其中一个复选框被选中时,表单有效。而且看起来像

formValidator(control: AbstractControl):  [key: string]: any  
   return control.value.rows.some(i => i.checkbox_value) ? null :  'checkboxReq': 'Some checkbox field is required' 

将其添加到您的表单中

this.myForm.setValidators([this.formValidator.bind(this)])

在模板中你可以通过myForm.getError('checkboxReq')得到它

<small class="form-text text-muted danger">myForm.getError('checkboxReq')</small>

对于子表单需要另一个验证器

subFormValidator(control: AbstractControl):  [key: string]: any  
   return control.value.checkbox_value ?  'req': 'This field is required'  : null

在初始化子表单时添加它

(this.fb.group(
      checkbox_value: [null],
      material_id: [ value: x.id, disabled: true ],
      material_name: x.name,
      quantity: [null]
    , [this.subFormValidator.bind(this)]));

模板

<small class="form-text text-muted danger" *ngIf="row.invalid && row.touched">This field is required</small>

stackblitz example with changes

【讨论】:

您好,谢谢您。我的 patchValues 函数有问题。你能不能改变我的补丁值,因为在我自己的应用程序上它说 this.data.reduce 不是一个函数。你能回到我的 patchValues 的样子吗?谢谢 reduce 是我使用的默认数组方法 (developer.mozilla.org/en-US/docs/Web/javascript/Reference/…),因为我想要扁平内部数组。如果你没有内部数组,只需删除 reduce。使用 reduce 和 map 比使用 forEach 和 push 更好。 而且我已经实现了我的自定义验证器,它说数量不应超过可用数量,我不知道如何将它与您的自定义验证器结合起来。你能帮忙吗。检查这个stackblitz.com/edit/… 在数组中添加了验证器。只需在我的[this.formValidator.bind(this), this.anotherFormValidator.bind(this)] 之后添加您的验证器 您好,收到了吗?

以上是关于Angular 反应式表单自定义验证器。仅在选中复选框时启用验证的主要内容,如果未能解决你的问题,请参考以下文章

Angular 反应复选框仅在第一次单击后正确切换

使用自定义验证和动态值的 Angular 表单

验证不会传播到 Angular 中的自定义表单控件 ng-select

FormArray 字段的角度自定义验证(反应式表单)

使用反应式表单在 Angular 中检查后,表达式发生了变化

Angular 2 - 自定义表单控件 - 禁用