自定义验证器问题:嵌套数组需至少选中1项的验证失效
Angular嵌套表单数组自定义验证器修复方案
问题根源
你的验证器存在两个问题:
reduce逻辑错误:acc + value.value.length仅计算了数值,但未重新赋值给acc,导致每次循环acc始终保持初始值0,最终totalSelected一直为0。- 逻辑不符合需求:你需要的是任意一个数组有至少1项即通过验证,而非累加所有数组的总项数,用累加判断属于冗余逻辑。
修复后的验证器代码
static minItemsInFormGroupNestedFormArrays(min = 1) { const validator: ValidatorFn = (formGroup: AbstractControl) => { if (formGroup instanceof FormGroup) { // 检查是否存在至少一个符合长度要求的表单数组 const hasValidArray = Object.values(formGroup.controls).some(control => { return control instanceof FormArray && control.value.length >= min; }); return hasValidArray ? null : { required: true }; } throw new Error('formGroup is not an instance of FormGroup'); }; return validator; }
代码说明
- 用
some替代reduce:some方法会在找到第一个满足条件的元素时立即终止遍历,既贴合需求又提升性能。 - 增强类型校验:增加
control instanceof FormArray判断,避免表单组混入非数组控件时出现异常。 - 若后续需保留累加逻辑(非当前需求),正确写法应为:
const totalSelected = Object.values(formGroup.controls).reduce((acc, control) => { return acc + (control instanceof FormArray ? control.value.length : 0); }, 0);
内容的提问来源于stack exchange,提问作者Andrew Howard
相关产品推荐
相关产品推荐

