我创建了一个自定义验证器来验证FormArray中的唯一性.我想在特定(s)值已经在数组中时显示错误.
问题是它没有按预期工作.
实际行为:
重现步骤:
>添加3“输入” – 地址;
>填写输入1;
>使用不同的值填充输入2;
>使用相同的输入值1填充输入3; (输入1和输入3均未出现错误)
预期行为:
在上述情况下,错误应出现在输入1和3上.
假设我有4个输入:
>值:堆栈
>价值:溢出
>值:堆栈
>价值:溢出
static uniqueBy = (field: string,caseSensitive = true): ValidatorFn => { return (formArray: FormArray): { [key: string]: boolean } => { const controls = formArray.controls.filter(formGroup => { return isPresent(formGroup.get(field).value); }); const uniqueObj = { uniqueBy: true }; let found = false; if (controls.length > 1) { for (let i = 0; i < controls.length; i++) { const formGroup = controls[i]; const mainControl = formGroup.get(field); const val = mainControl.value; const mainValue = caseSensitive ? val.toLowerCase() : val; controls.forEach((group,index) => { if (i === index) { // Same group return; } const currControl = group.get(field); const tempValue = currControl.value; const currValue = caseSensitive ? tempValue.toLowerCase() : tempValue; let newErrors; if ( mainValue === currValue) { if (isBlank(currControl.errors)) { newErrors = uniqueObj; } else { newErrors = Object.assign(currControl.errors,uniqueObj); } found = true; } else { newErrors = currControl.errors; if (isPresent(newErrors)) { // delete uniqueBy error delete newErrors['uniqueBy']; if (isBlank(newErrors)) { // {} to undefined/null newErrors = null; } } } // Add specific errors based on condition currControl.setErrors(newErrors); }); } if (found) { // Set errors to whole formArray return uniqueObj; } } // Clean errors return null; }; }
你可以在这里查看DEMO.
在您的代码中使用嵌套for循环,您正在交错错误.
以下是验证状态查找每次迭代的方式:
0 [null,"{"uniqueBy":true}",null] 1 ["{"uniqueBy":true}",null] 2 [null,"{}",null]
http://plnkr.co/edit/MTjzQ9KiJHJ56DVAZ155?p=preview(添加三个地址并观察输出)
在下面的代码中,我只在loop语句之前清除错误一次,不再删除错误.
controls.map(formGroup => formGroup.get(field)).forEach(x => x.errors && delete x.errors['uniqueBy']); for (let i: number = 0; i < controls.length; i++) { const formGroup: FormGroup = controls[i] as FormGroup; const mainControl: AbstractControl = formGroup.get(field); const val: string = mainControl.value; const mainValue: string = caseSensitive ? val.toLowerCase() : val; controls.forEach((group: FormGroup,index: number) => { if (i === index) { return; } const currControl: any = group.get(field); const tempValue: string = currControl.value; const currValue: string = caseSensitive ? tempValue.toLowerCase() : tempValue; let newErrors: any; if ( mainValue === currValue) { if (isBlank(currControl.errors)) { newErrors = uniqueObj; } else { newErrors = Object.assign(currControl.errors,uniqueObj); } currControl.setErrors(newErrors); find = true; } }); }