Как предоставить асинхронный параметр для пользовательских угловых валидаторов - PullRequest
1 голос
/ 12 мая 2019

Я устанавливаю валидаторы форм, где минимальное и максимальное количество полей выбираются через один API.Приложение вылетает при попытке передать одно из этих асинхронных значений в пользовательский параметр валидатора, но оно будет работать, когда значение жестко запрограммировано.

Ошибка, полученная при передаче асинхронного значения, следующая:

ОШИБКА: formGroup ожидает экземпляр FormGroup.Пожалуйста, введите один.

file.ts:

export class PackageDimensionValidator {
   static validSize(min: number, max: number): ValidatorFn {
      return (control: AbstractControl): { [key: string]: boolean } | null => {
      if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
        return { 'exceedRange': true };
      }
      return null;
    };
   }
}

// ... 

ngOnInit() {
   // Retrieve maximum package dimensions for input data validation.
   this.shipmentService.getMaxPackageSize()
      .subscribe(result => {
         this.packageRestrictions = new PackageRestrictions(result);
         console.dir(this.packageRestrictions);
         this.setupPackageValidators();
   });
}

setupPackageValidators() {
   const maxWidth = this.packageRestrictions.maxWidth; // Crashes on Async value.
   // const maxWidth = 5; // Works on hard-coded value.

   // Setup package dimension validators.
   this.packageSizeForm = this.formBuilder.group({
      maxWidth: new FormControl('', Validators.compose([
         PackageDimensionValidator.validSize(null, maxWidth),
         // Other validators ...
      ]))
   });
}

file.html:

<form [formGroup]="packageSizeForm">
   <input formControlName="maxWidth" type="text" required />
</form>

В идеале должно быть несколько formControls каждый с уникальными минимальными и максимальными значениями, которые все выбираются одновременно одним API.Мысленный процесс состоял в том, чтобы вызвать этот API, сохранить его результат локально, а затем создать валидаторы формы.Сейчас я подвергаю сомнению порядок этой последовательности.

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Я не совсем уверен, что полученное вами сообщение об ошибке отражает описанную вами проблему.Я бы начал с Инициирования packageSizeForm в вашем ngOnInit без валидаторов:

ngOnInit() {
   this.packageSizeForm = new FormGroup({
          maxWidth: new FormControl('');
   });
   this.shipmentService.getMaxPackageSize()
      .subscribe(result => {
         this.packageRestrictions = new PackageRestrictions(result);
         console.dir(this.packageRestrictions);
         this.setupPackageValidators();
   });
}

Затем установите валидаторы в this.setupPackageValidators();:

setupPackageValidators() {
   this.packageSizeForm.get('maxWidth').clearValidators();
   this.packageSizeForm.get('maxWidth').setValidators(Validators.compose([
     PackageDimensionValidator.validSize(null, maxWidth)]);
   this.packageSizeForm.get('maxWidth').updateValueAndValidity();
}
0 голосов
/ 12 мая 2019

Возможно, вы захотите использовать асинхронные валидаторы

https://angular.io/api/forms/AsyncValidator

asyncValidator передается в качестве необязательного третьего параметра в конструктор FormControl:

class FormControl {
  ...
  constructor(
    formState: any = null,
    validatorOrOpts?: ValidatorFn | AbstractControlOptions | ValidatorFn[],
    asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[]
  )
  ...
}
...