Angular FormArray - 重复值验证器

时间:2018-06-12 10:46:11

标签: angular angular-reactive-forms

我正在使用带反应形式的Angular 6。其中一个表单字段是FormArray,它在用户单击“添加”按钮时添加控件。

在FormArray中,我想检查FormArray中是否已存在FormControl值。

这样可以正常工作,直到用户单击“添加”按钮重置上一个控件错误并将控件标记为有效,尽管它仍然具有重复值。

这是在表单数组中添加控件的功能:

onAddIPAddress() {

  if (( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).length < 8) {

    const control = new FormControl(null, Validators.compose([
      Validators.required,
      Validators.pattern(this.ipaddressPattern),
      this.forbiddenIPs.bind(this),
      this.onDuplicateIPFormArray.bind(this)
    ]));


    ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).push(control);


  } else {
    return;
  }

}

然后,这是自定义验证器代码:

onDuplicateIPFormArray(control: FormControl): {
  [s: string]: boolean
} {

  if (
    ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).length > 1 &&
    !( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value.includes(null) &&
    ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value.indexOf(control.value) !== -1)

  {
    console.log(( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value.indexOf(control.value));

    return {
      duplicateIP: true
    };
  }

  return null;

}

从控制台,我可以看到IndexOf值不正确但无法理解原因。

我有什么想法可以解决这个问题吗?

由于

1 个答案:

答案 0 :(得分:1)

好的,所以我已经改变了应该如何进行验证,看起来好多了:

  • 从各个FormArray控件中删除自定义Validator。

  • 将重复的项目自定义验证器放在FormArray本身上。

if ($event.value ===
  'ip-address') {
  this.tcpudpAppFormGroup.addControl('ipaddressArray', new FormArray([], Validators.compose([
    Validators.required,
    this.onDuplicateIPFormArray.bind(this)

  ])));

然后创建FormArray验证器作为标准函数来检测数组中的重复项:

onDuplicateIPFormArray() {

  if (( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray'))) {

    let counts = [];

    for (let i = 0; i < ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).length; i++) {
      if (counts[( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value[i]] === undefined) {
        counts[( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).value[i]] = 1;
      } else {
        console.log(counts);
        ( < FormArray > this.tcpudpAppFormGroup.get('ipaddressArray')).controls[i].setErrors({
          duplicateIP: true
        });
        
      }
    }
  }
}