Angular реактивные формы и ошибка настраиваемого валидатора

В моем приложении Angular 4 у меня есть валидатор настраиваемой формы, который выглядит следующим образом :

import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export function myCustomValidator(myCustomArg: string): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {

    if (control.value) {
      // do some checks with control.value and myCustomArg
      // return error if needed
    }

    // return null otherwise
    control.setErrors(null);
    return null;
  };
}

но когда я пытаюсь использовать его в одной из моих реактивных форм:

  ngOnInit() {
    this.form = new FormGroup({
      'myControl': new FormControl(null, [ myCustomValidator(...) ]),
      // ...
    });
  }

Получаю несколько ошибок:

ОШИБКА TypeError: невозможно прочитать свойство 'emit' of undefined в FormControl.webpackJsonp ... / .. / .. / forms/@angular/forms.es5.js.AbstractControl._updateControlsErrors (forms.es5.js: 2836) в FormControl .webpackJsonp ... / .. / .. / forms/@angular/forms.es5.js.AbstractControl.setErrors (forms.es5.js: 2772) в file-extension.validator.ts: 17 в forms.es5. js: 506 в Array.map () в _executeValidators (forms.es5.js: 506) в FormControl.validator (forms.es5.js: 462) в FormControl.webpackJsonp ... / .. / .. / forms / @ angular / forms.es5.js.AbstractControl._runValidator (forms.es5.js: 2720) в FormControl.webpackJsonp ... / .. / .. / forms/@angular/forms.es5.js.AbstractControl.updateValueAndValidity (forms .es5.js: 2688) в новом FormControl (forms.es5.js: 3011)


КОНТЕКСТ ОШИБКИ DebugContext_ {view: {…}, nodeIndex: 0, nodeDef: {…}, elDef: {…}, elView: {…}}


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

Но, к сожалению, они не очень полезны.


person Francesco Borzi    schedule 21.10.2017    source источник


Ответы (1)


Проблема связана с тем, как валидатор назначается полю.

Фактически, валидатор пытается получить доступ к значению элемента управления control.value.

Но когда вызывается фабричная функция валидатора, элемент управления еще не существует:

this.form = new FormGroup({
  'myControl': new FormControl(null, [ myCustomValidator(...) ]),
  // ...
});

Итак, чтобы решить эту проблему, просто сначала создайте форму, а затем назначьте валидатор:

ngOnInit() {
   // first create the form with its controls
  this.form = new FormGroup({
    'myControl': new FormControl(null),
    // ...
  });

  // then assign the custom validator
  this.form.get('myControl').setValidators([
    myCustomValidator(...),
  ]);
}
person Francesco Borzi    schedule 21.10.2017