首页 > 解决方案 > 从它的OWN数据显示的Angular 6 Reactive Forms自定义验证器错误

问题描述

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

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

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

问题步骤: 单击 Additional Assignment => 选择 Position、Department 和 Location 与上一行相同。=> 你会看到错误,“Same Job data” => 现在将 Position 的值更改为其他值 => 没有错误 => 更改 Pay Rate 输入中的值 => 你会看到错误,“Same Job data " > 因为它将更改的行与肯定返回 True 的表单数据中的数据进行比较。

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

我只检查职位、部门和位置之间的相似性。

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:更改位置选择值和错误消失 位置改变,错误消失

图 3:在 Pay Rate 输入中输入一些数字,然后再次显示错误。 输入工资率更改并出现错误

标签: angularangular5angular6angular-reactive-formsangular-forms

解决方案


除了检查条件外,您的实现看起来非常好。由于您没有任何唯一的行 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

推荐阅读