Angular 9+ asyncValidator с противодействием
@ n00dl3 имеет правильный ответ. Мне нравится полагаться на код Angular, чтобы отказаться от подписки и создать новый асинхронный валидатор, добавив временную паузу. API-интерфейсы Angular и RxJS эволюционировали с тех пор, как был написан этот ответ, поэтому я публикую обновленный код.
Также я внес некоторые изменения. (1) Код должен сообщать об обнаруженной ошибке, а не скрывать ее под совпадением в адресе электронной почты, иначе мы запутаем пользователя. Если сеть не работает, почему говорят, что адрес электронной почты соответствует ?! Код представления пользовательского интерфейса будет различать столкновение электронной почты и ошибку сети. (2) Валидатор должен зафиксировать значение элемента управления до временной задержки, чтобы предотвратить любые возможные состояния гонки. (3) Используйте delay
вместо timer
, потому что последний будет срабатывать каждые полсекунды, и если у нас медленная сеть и проверка электронной почты занимает много времени (одна секунда), таймер продолжит перезапуск switchMap, и вызов никогда не завершится.
Фрагмент, совместимый с Angular 9+:
emailAvailableValidator(control: AbstractControl) {
return of(control.value).pipe(
delay(500),
switchMap((email) => this._service.checkEmail(email).pipe(
map(isAvail => isAvail ? null : { unavailable: true }),
catchError(err => { error: err }))));
}
PS: Всем, кто хочет глубже изучить исходники Angular (я настоятельно рекомендую), вы можете найти код Angular, который выполняет асинхронную проверку здесь и код отмены подписки здесь, который вызывает this. Все тот же файл и все под updateValueAndValidity
.
person
Andrew Philips
schedule
30.06.2020