По умолчанию validateSomeNumber
вызывается после каждого изменения значения.
Если вы возвращаете это при каждом изменении значения
return control.valueChanges.pipe(
debounceTime(1000),
distinctUntilChanged(),
...
)
вы создаете новую Наблюдаемость изменений значения при каждом изменении значения. изменение значения. Например, если вы наберете четыре символа, вы получите четыре независимых Observable, каждый из которых испускает один символ, а не один Observable, испускающий четыре раза. Таким образом, debounceTime
и distinctUntilChanged
будут влиять только на Наблюдаемую информацию, которую вы создаете, на конкретное изменение значения, но не на процесс изменения значения в целом. Если они влияют только на Observable, который излучает, как только они, очевидно, не работают так, как вы намереваетесь.
Вы должны вернуть http-запрос напрямую
validateSomeNumber(control: FormControl): Observable<any> | Promise <any> {
this.isSubmitBtnDisabled = true;
return this.apiService.someApiRequest({ 'to_number': control.value }).pipe(
map(..),
);
}
Ограничение частоты запросов
Опция 1: updateOn
Для предотвращения выполнения запроса http при каждом изменении значения Angular рекомендует изменить свойство updateOn
на submit
или blur
.
С шаблонными формами:
<input [(ngModel)]="name" [ngModelOptions]="{updateOn: 'blur'}">
С реактивными формами:
new FormControl('', {updateOn: 'blur'});
{updateOn: 'blur'}
будут выполнять валидаторы только тогда, когда Ваш ввод теряет фокус.
Вариант 2: эмулировать debounceTime и diver-only-UntilChanged
Angular автоматически отписывается от предыдущего Observable, возвращаемого AsyncValidator, если изменяется значение формы. Это позволяет вам эмулировать debounceTime
с timer
. Чтобы подражать distinctUntilChanged
, вы можете отслеживать последний термин запроса и самостоятельно проверять равенство.
private lastRequestTerm = null;
validateSomeNumber(control: FormControl): Observable<any> | Promise <any> {
this.isSubmitBtnDisabled = true;
// emulate debounceTime
return timer(1000).pipe(
// emulate distinceUntilChanged
filter(_ => control.value != this.lastRequestTerm),
switchMap(() => {
this.lastSearchTerm = control.value;
return this.apiService.someApiRequest({ 'to_number': control.value });
}),
map(..)
);
}