Angular: Validators.email недействителен, если пустой

Я создаю приложение в Angular (4.0), которое содержит форму (FormGroup). В этой форме у меня есть ввод электронной почты (с FormControl), и я использую Validators.email для проверки.

import { Validators } from '@angular/forms';

// ...
let validators = [];
if ([condition]) {
    validators.push(Validators.email);
}
let fc = new FormControl([value] || '', validators);
// ...

Но когда вход пуст, он недействителен (он имеет класс ng-invalid), даже если он не требуется.

Это правильное поведение? Что я могу сделать?

Ответ 1

Однако решение

eric2783 довольно неплохое - если в будущем результат работы Validators.email изменится, тогда этот пользовательский валидатор станет несовместимым с выходным сигналом angular.

Здесь вы должны сделать, чтобы сохранить совместимость:

private customEmailValidator(control: AbstractControl): ValidationErrors {
  if (!control.value) {
    return null;
  }

  return Validators.email(control);
}

Ответ 2

Лучшим решением, которое я нашел, было следующее:

<input type="email" name="email" [(ngModel)]="model.Email" [email]="model.Email!='' && model.Email!=null">

Ответ 3

Временное решение в формах, управляемых шаблонами:

<input [(ngModel)]="model.email"  [email]="model.email!==''">

Это сработало для меня (убедитесь, что инициализируется значение модели пустой строкой).

Ответ 4

Вы можете выполнить то, что хотите, с помощью специального валидатора. Здесь валидатор, который я написал, чтобы заставить его работать:

private customEmailValidator(control: AbstractControl): {[key: string]: any} {
    const emailError = Validators.email(control);
    if (control.value && emailError) {
        return {'email': {}};
    }

    return null;
}

Затем вы можете заменить validators.push(Validators.email); на validators.push(this.customEmailValidator);

Он использует angular встроенный модуль проверки подлинности электронной почты, но также гарантирует, что элемент управления электронной почты имеет значение перед возвратом ошибки.

Ответ 5

Самая короткая форма для этого:

<input [(ngModel)]="model.email" [email]="!!model.email">