Динамически добавить валидатор

У меня есть 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();

Но я получаю ту же ошибку


person Tzimpo    schedule 23.03.2020    source источник


Ответы (3)


this.reps — это formArray, поэтому вам следует изменить

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

by

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();
person Ghoul Ahmed    schedule 23.03.2020

Прежде всего, не используйте .controls для получения указанного контроля. Используйте get(). Вы получаете исключение, потому что ваш this.reps равен FormArray, и при доступе к свойству controls вы получаете такой объект:

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

Как видите, поля mobileNumber в this.reps нет. Вы должны получить прямой доступ к formControl, чтобы получить mobileNumber formControl. Или вы можете напрямую добавить validator в поле во время создания формы, как это делалось ранее. Если ваша логика проверки подтверждает f.e. уникальность номера, вам нужно прикрепить валидатор к вашему FormArray (или FormGroup, в зависимости от того, что вы используете), а не напрямую к FormControl.

person KamLar    schedule 23.03.2020

Поскольку ForArray основан на индексе, вы должны использовать значение индекса для получения определенных элементов управления formGroup.

Попробуйте это:

this.reps.at(0).get('mobileNumber').setValidators([=[Validators.required,Validators.pattern(/^(69[0-9])[0-9]{7}$/),this.ValidateNames])
person Chellappan வ    schedule 23.03.2020
comment
Итак, каждый раз, когда я добавляю newRep, мне нужно передать индекс этого метода, чтобы добавить валидатор к правильному элементу управления? - person Tzimpo; 23.03.2020