【问题标题】:Dynamically add validator动态添加验证器
【发布时间】:2020-03-23 16:07:16
【问题描述】:

我有一个 formArray,点击时我正在调用 addReps 方法来推送一个新的 formGroup。我想使用 setValidators 方法动态添加一些验证器,但是当我这样做时,我得到了错误: 无法读取未定义的属性“setValidators”。我的表单工作正常,但我不明白为什么会出现此错误。我的 formControl 访问 this.reps.controls["mobileNumber"] 是否有问题?

constructor(private fb: FormBuilder, private stateService: StateService, private apiService: ApiService) {
   this.form = this.fb.group({
     reprepresentative: this.fb.array([]),
   });
}

addReps() {
  this.reps = this.form.controls.reprepresentative as FormArray;
  this.reps.push(this.fb.group({
    firstname: ['', [Validators.required,
     Validators.minLength(2),
     this.ValidateNames
    ]],
    surname: ['', [Validators.required,
     Validators.minLength(2),
     this.ValidateNames
   ]],
   mobileNumber: ['', [Validators.required,
    Validators.pattern(/^(69[0-9])[0-9]{7}$/)
    ]],
  isInitiator: false,
  editRep: true
  }));
  this.reps.controls["mobileNumber"].setValidators([this.SameMobileValidator,Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/)]);
  this.reps.controls["mobileNumber"].updateValueAndValidity();
}

SameMobileValidator(formControl: AbstractControl){
   let repList = this.stateService.reprepresentativeList;
   const found = repList.some(el => el.MobilePhone == formControl.value)
   if(!found) return null;
   else { return { mismatch: true }; }
}

我也试试这个:

  this.reps.get("mobileNumber").setValidators([Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/),this.ValidateNames]);
this.reps.get("mobileNumber").updateValueAndValidity();

但我遇到了同样的错误

【问题讨论】:

    标签: angular angular-reactive-forms angular-validation


    【解决方案1】:

    this.reps 是一个formArray,所以你应该改变

    this.reps.controls["mobileNumber"].setValidators([this.SameMobileValidator,Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/)]);
    

    通过

    const reprepresentativeControl = this.form.get('reprepresentative');
    reprepresentativeControl.controls.forEach(c => c.get("mobileNumber").setValidators([this.SameMobileValidator,Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/)]));
    reprepresentativeControl.updateValueAndValidity();
    

    【讨论】:

      【解决方案2】:

      首先,不要使用.controls 来获得指定的控制权。使用get()。你得到一个例外,因为你的 this.reps 是 FormArray 当你访问 controls 属性时,你会得到这样的对象:

      {
          1: [formControl],
          2: [formControl],
          3: [formControl]
      }
      

      如您所见,this.reps 中没有字段 mobileNumber。您必须直接访问formControl 才能获得mobileNumber formControl。或者,您可以在构建表单时直接将validator 添加到字段中,就像之前所做的那样。如果您的验证逻辑验证 f.e.编号唯一性,您必须在 FormArray(或 FormGroup,取决于您使用的内容)上而不是直接在 FormControl 上附加验证器。

      【讨论】:

        【解决方案3】:

        由于 ForArray 是基于索引的,因此您可以使用索引值来获取特定的 formGroup 控件。

        试试这个:

        this.reps.at(0).get('mobileNumber').setValidators([=[Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/),this.ValidateNames])
        

        【讨论】:

        • 所以每次我添加一个 newRep 我都必须在这个方法上传递索引才能将验证器添加到正确的控件?
        猜你喜欢
        • 2017-09-22
        • 2018-08-11
        • 2012-09-29
        • 1970-01-01
        • 2016-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-19
        相关资源
        最近更新 更多