我创建了一个自定义验证器来验证FormArray中的唯一性.我想在特定(s)值已经在数组中时显示错误.
@H_502_1@问题是它没有按预期工作.
@H_502_1@实际行为:
@H_502_1@重现步骤:
@H_502_1@>添加3“输入” – 地址;
>填写输入1;
>使用不同的值填充输入2;
>使用相同的输入值1填充输入3; (输入1和输入3均未出现错误) @H_502_1@预期行为: @H_502_1@如果“X组”中显示相同的值,则其特定输入必须显示错误. @H_502_1@在上述情况下,错误应出现在输入1和3上. @H_502_1@假设我有4个输入: @H_502_1@>值:堆栈
>价值:溢出
>值:堆栈
>价值:溢出 @H_502_1@4个输入必须显示错误,因为它们都是重复的.
>填写输入1;
>使用不同的值填充输入2;
>使用相同的输入值1填充输入3; (输入1和输入3均未出现错误) @H_502_1@预期行为: @H_502_1@如果“X组”中显示相同的值,则其特定输入必须显示错误. @H_502_1@在上述情况下,错误应出现在输入1和3上. @H_502_1@假设我有4个输入: @H_502_1@>值:堆栈
>价值:溢出
>值:堆栈
>价值:溢出 @H_502_1@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; }; }@H_502_1@你可以在这里查看DEMO.
在您的代码中使用嵌套for循环,您正在交错错误.
@H_502_1@以下是验证状态查找每次迭代的方式:
0 [null,"{"uniqueBy":true}",null] 1 ["{"uniqueBy":true}",null] 2 [null,"{}",null]@H_502_1@http://plnkr.co/edit/MTjzQ9KiJHJ56DVAZ155?p=preview(添加三个地址并观察输出) @H_502_1@在下面的代码中,我只在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; } }); }@H_502_1@Plunker Example