Angular 6 Reactive Forms Custom Validator Error 从它自己的数据中显示出来

Angular 6 Reactive Forms Custom Validator Error Displayed from it's OWN data

我在 FormGroup 中有一个 FormArray,每个 FormArray 都有多个 FormGroup,并且可以动态添加它们。

我有一个自定义验证器,它检查每个 FormArray 中的所有数据以验证数据的重复。 它有一个问题,FormArray 中的单个 FormGroup 正在将它与 FormArray 中的所有数据进行比较并且 returning True 因为 FormGroup 存在于 FormArray

StackBlits link: https://stackblitz.com/edit/angular-custom-validator-defaultdata

问题步骤: 点击Additional Assignment => Select Position, Department and Location 同上一行。 => 你会看到错误,“相同的工作数据 " => 现在将 Position 的值更改为其他值 => 无错误 => 更改 Pay Rate 输入中的值 => 你会看到错误,“相同的工作数据 " > 因为它将更改的行与来自表单数据的数据进行比较,这肯定 return True。

有什么方法可以限制错误在检查自己的数据时抛出自己吗?

我只是在检查 Position、Department 和 Location 之间的相似性。

for (let assign of this.additionalAssign) {
      const fg = new FormGroup({
        "payRate": new FormControl(assign.jobRate, Validators.required),
        "position": new FormControl(assign.position, Validators.required),
        "location": new FormControl(assign.location, Validators.required),
        "department": new FormControl(assign.department, Validators.required)
      }); 
      fg.validator = this.jobDataValidator.bind(this);
      this.addPay.push(fg);
    }

验证者:

jobDataValidator(control: FormControl): {[s: string]: boolean} {
    let value = this.getJobLocDeptValidity(control);
    if(value.length > 0 && control.dirty){
      return {'sameJobData': true};
    }
    return null;
  }

  getJobLocDeptValidity(control: FormControl):any[] {
    let additionalAssignments = this.additionalAssignmentsForm.value.payArray;
    let test = additionalAssignments.filter(item =>  !!control.value.position && item.position === control.value.position && !!control.value.department && item.department === control.value.department && !!control.value.location && item.location === control.value.location);
    return test;
  }

图 1:新行(第 3 行)数据与前行(第 2 行)相同 => 显示错误

图 2:更改位置 select 值,错误消失

图 3:在支付率输入中输入一些数字,再次显示错误。

除了检查条件外,您的实现看起来非常好。由于您没有行的任何唯一 ID,因此很难匹配记录是否存在或现在。

不过你很幸运能够引用所有需要的对象。您可以检查对象是否匹配。

只需在验证部分添加一个条件

control !== item 

下面是修改后的代码-

  getJobLocDeptValidity(control: FormControl):any[] {

    let additionalAssignments = this.additionalAssignmentsForm.value.payArray;
    let test = additionalAssignments.filter(item =>  
    control !== item && !!control.value.position && item.position === control.value.position && !!control.value.department && item.department === control.value.department && !!control.value.location && item.location === control.value.location);
    return test;
  }

更新

由于您 index 并且根据您的评论,下面的检查有效。

control.index !== item.i

我已经分叉了您的示例应用程序并对代码做了一些小改动。现在它按预期工作。请参阅 stackblitz

我做了下面列出的三项更改:

  1. 您在行级别没有任何 uniqueid,我已将其添加为您的 'this.addPay' 长度的索引。请参阅行号:57 和 75。
  2. 'getJobLocDeptValidity' 方法中检查当前控件索引和过滤器索引的应用条件不应相同,并进行了一些其他更改。

这是您的 getJobLocDepValidity 的代码更改。

 getJobLocDeptValidity(control: FormControl):any[] {
    let additionalAssignments = this.additionalAssignmentsForm.value.payArray;
    let test = additionalAssignments.filter(item => {
if(control.value.index != item.index){
return (item.payRate == control.value.payRate && item.position == control.value.position && item.department == control.value.department && item.location == control.value.location)
}
return false;
    } );
    return test;
  }

@Sunil 我建议,请尝试给出正确答案并在提供输入之前对其进行测试,以便有人可以轻松实现而无需任何错误代码。

您可以像这样尝试从验证器中排除 payRate 值:

jobDataValidator(control: FormControl): {[s: string]: boolean} {
    let value = this.getJobLocDeptValidity(control);
    if(value.length > 0 && control.dirty  && !control.value.payRate){
      return {'sameJobData': true};
    }
    return null;
  }