Я создаю регистрационную форму с реактивными формами, где клиент должен вставить адрес электронной почты. Я добавил асинхронный валидатор в этот элемент управления, чтобы проверить, используется ли уже введенное электронное письмо.
this.form = this.formBuilder.group({
...,
emailGroup: this.formBuilder.group({
email: ['', [Validators.required, Validators.email], uniqueEmailValidator(this.registerService)],
confirmEmail: ['', [Validators.required]]
}, { validator: emailMatcher }),
...
});
Мой HTML выглядит так:
<div class="col-sm-6">
<div class="form-group">
<label for="reg-email">E-mailadres</label>
<input class="form-control" type="text" id="reg-email" formControlName="email" [ngClass]="{'is-invalid': form.get('emailGroup.email').errors && (form.get('emailGroup.email').touched || isSubmitted)}">
<div class="invalid-feedback">
<div *ngIf="form.get('emailGroup.email').errors?.required || form.get('emailGroup.email').errors?.email">
Please insert a valid email
</div>
<div *ngIf="form.get('emailGroup.email').errors?.uniqueEmail">
This email is already in use
</div>
</div>
</div>
</div>
Первоначально мой асинхронный валидатор выглядит так:
export function uniqueEmailValidator(registerService: RegisterService): AsyncValidatorFn {
return (c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
return registerService.getCustomersByEmail(c.value).pipe(
map(customers => {
return customers && customers.length > 0 ? { 'uniqueEmail': true } : null;
})
);
}
}
Все работает правильно до сих пор. Когда я вставляю существующее письмо, я получаю сообщение об ошибке «это письмо уже используется».
Я заметил, что этот асинхронный валидатор выполнялся для каждого вставленного символа, и по соображениям производительности я хочу этого избежать. Я решил добавить таймер на 500 мс и выполнять асинхронную проверку только тогда, когда нет активности в течение 500 мс. Это меняет мой асинхронный валидатор на это:
export function uniqueEmailValidator(registerService: RegisterService): AsyncValidatorFn {
return (c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
return timer(500).pipe(
map(x => {
return registerService.getCustomersByEmail(c.value).pipe(
map(customers => {
return customers && customers.length > 0 ? { 'uniqueEmail': true } : null;
})
);
})
);
};
}
Валидатор выполняет работу правильно, а элемент управления электронной почтой помечается как недействительный после асинхронной проверки. Проблема в том, что мой html больше не отображает сообщение об ошибке «Это письмо уже используется». Код ошибки «uniqueEmail» не добавляется в объект ошибок моего элемента управления.
Может кто-нибудь пролить свет на этот?
Заранее спасибо.