DebounceTime испускает все события, которые были зафиксированы за время - PullRequest
0 голосов
/ 13 мая 2019

Мне нужно написать асинхронный валидатор для типа реактивной формы в угловых. Я реализовал это через обещание. Но проблема заключается в том, что триггеры валидатора для каждого нажатия клавиши попадают на сервер при каждом нажатии клавиши. Для реализации дебаза я реализовал setTimeout для обещания, но проблема, с которой я столкнулся, заключается в том, что он срабатывает после определенного миллисекунды, который я определил. Наконец, я реализовал Observable внутри обещания достичь всех debounceTime, но проблема, с которой я здесь столкнулся, заключается в том, что debounceTime генерирует все события. Например: если я наберу «Prem» из поля ввода, следующий код запускает сервер четыре раза по истечении времени ожидания.

Если есть какие-либо проблемы в реализации асинхронного валидатора, пожалуйста, сообщите мне.

//Latest code
static hasDuplicateEmail(formControl: FormControl) {
        return new Promise((resolve, reject) => {
            return new Observable(observer => 
               observer.next(formControl.value)).pipe(
                debounceTime(600),
                distinctUntilChanged(),
                switchMap((value) => {
                    //server side
                    return MotUtil.fetch('checkForRegisterEmail', {e: formControl.value});
                })
            ).subscribe((res) => {
                return (JSONUtil.isEmpty(res)) ? resolve(null) : resolve({duplicate: true});
            });
        });
    }

DebounceTime должно работать, как указано в Документах.

1 Ответ

2 голосов
/ 13 мая 2019

Вы пытаетесь приблизиться к нему трудным способом. Валидатор принимает аргумент - AbstractControl . AbstractControl имеет свойство - valueChanges, которое возвращает поток изменений в вашем formControl. Итак, вы добавляете debouceTime, а затем выполняете другие операции и, наконец, возвращаете этот поток обратно в FormControl:

hasDuplicateEmail(control: AbstractControl) {
  return control.valueChanges.pipe(
    debounceTime(600),
    switchMap(e => 
      this.http.get('checkForRegisterEmail', {e}).pipe(
        map((res: any) => JSONUtil.isEmpty(res) ? null : { duplicate: true })
      )
    )
  )
}

Как вы заметили, я использую HttpClient , так как вы делаете HTTP-вызовы в Angular (он предназначен для работы с потоками, а не с Promises)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...