Как запускать валидаторы форм в Angular2

82

В angular2 я хочу запускать валидаторы для некоторых элементов управления при изменении другого элемента управления. Есть ли способ просто указать форме на повторную проверку? Еще лучше, могу ли я запросить проверку определенных полей?

Пример: задан флажок X и вход P. На входе P есть валидатор, который ведет себя по-разному в зависимости от значения модели X. Когда X отмечен / не отмечен, мне нужно вызвать валидатор на P. Валидатор на P будет смотреть на модель, чтобы определяет состояние X и соответственно проверяет P.

Вот код:

constructor(builder: FormBuilder) {
    this.formData = { num: '', checkbox: false };

    this.formGp = builder.group({
        numberFld: [this.formData.num, myValidators.numericRange],
        checkboxFld: [this.formData.checkbox],
    });
}

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
        // I want to be able to do something like the following line:
        this.formGp.controls['numberFld'].validator(this.formGp.controls['numberFld']);
    }
});

У кого-нибудь есть решение? Благодаря!

Bonneville
источник
Вы просто пытаетесь включить / отключить проверку на основе значения X? Какие валидаторы вы используете? Вы можете заставить валидаторы выполняться в зависимости от условия в вашей области, но я не уверен, сработает ли этот подход для вас. См .: stackoverflow.com/questions/21370006/…
stephen.vakil
@ stephen.vakil - я использую angular2.
Bonneville
@Bonneville, не могли бы вы объяснить, как вы передаете состояние флажка в функцию проверки?
Варун Муллоли

Ответы:

79

Я не знаю, ищете ли вы все еще ответ, поэтому вот мои предложения:

Посмотри на это: Angular 2 - AbstractControl

Я думаю, что вы могли бы сделать следующее:

this.formGp.controls['checkboxFld'].valueChanges.observer({
    next: (value) => {
       this.formGp.controls['numberFld'].updateValueAndValidity();
    }
});

Это должно вызвать и запустить валидаторы. Кроме того, обновляется и состояние. Теперь у вас должна быть возможность проверить значение флажка в логике валидатора.

Надеюсь это поможет!

РЕДАКТИРОВАТЬ: обновленная ссылка и пример. Код изменился, пока я писал свой ответ.

EDIT_2: alpha.48 изменяет EventEmitter.observer на EventEmitter.subscribe!

EDIT_3: изменена ссылка на фактическую реализацию, добавлена ​​ссылка на документы

Валидатон-Гид

Документация FormControl

Nightking
источник
Спасибо @Nightking за предложение, попробую. Обратите внимание, что ваша ссылка не работает.
Bonneville
@Bonneville Спасибо за информацию. Они извлекли код формы в общее пространство имен. Вещи немного меняются на быстрые :). Я обновил ссылку на источник.
Nightking
Наконец-то я дошел до использования этого фрагмента кода, и, похоже, он у меня работает. Благодаря! Кстати, в вашем коде есть опечатка: в функции updateValueAndValidity () отсутствует буква «e». Ваш код обновился вместо обновления. Ура, это было большим подспорьем!
Bonneville
1
Ссылка не работает; может быть обновлен до github.com/angular/angular/blob/master/packages/forms/src/… хотя и не совсем то же самое. Можно также
Explosion Pills
1
Спасатель жизни !! Случай использования, в котором я застрял, - это когда пользователь отправляет форму, не касаясь ни одного элемента управления формой. Форма недействительна, но элементы управления не отображают сообщение об ошибке
Правин
43

с моей ControlGroup я делаю это, потому что у меня есть ошибки, проверяющие div при прикосновении

for (var i in this.form.controls) {
  this.form.controls[i].markAsTouched();
}

(this.form - моя контрольная группа)

kernowcode
источник
это действительно правильный ответ. Если вам нужен единичный ввод, this.form.controls ['name']. MarkAsTouched ();
chris_r
19

С помощью этого блога

ссылка на блог

Я нашел решение с комбинацией ответа Nightking

Object.keys(this.orderForm.controls).forEach(field => {
       const control = this.orderForm.get(field);
       control.updateValueAndValidity();

});

this.orderForm - это группа форм

Альтаир CA
источник
8

Это помогло мне

this.myForm.markAllAsTouched();
К. Иконго
источник
6

Есть более элегантные способы моделирования этого поведения - например, помещение вашего состояния в ReplaySubject и наблюдение за ним, а затем использование асинхронных валидаторов, наблюдающих за состоянием, - но псевдокодированный подход ниже должен работать. Вы просто наблюдаете за изменениями значений в флажке, обновляете модель соответствующим образом, а затем вызываете повторную проверку numberFld с помощью cal updateValueAndValidity.

constructor(builder: FormBuilder) {
  this.formData = { num: '', checkbox: false };
  const numberFld = builder.control(this.formData.num, myValidators.numericRange);

  const checkbox = builder.control(this.formData.checkbox);
  checkbox.valueChanges.map(mapToBoolean).subscribe((bool) => {
    this.formData.checked = bool;
    numberFld.updateValueAndValidity(); //triggers numberFld validation
  });

  this.formGp = builder.group({
      numberFld: numberFld,
      checkboxFld: checkbox
  });
}
Jmreidy
источник
0
static minMaxRange(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        if (Validators.min(min)(control)) { // if min not valid
            return Validators.min(min)(control);
        } else {
            return Validators.max(max)(control);
        }
    };
}
Погиарон
источник