Использование debounceTime & differentUntilChanged не работает при подписке на FormBuilder valueChanges - PullRequest
1 голос
/ 10 апреля 2019

Проще говоря, я хочу выполнить запрос после того, как пользователь перестанет печатать в течение заданного промежутка времени. В каждом уроке, который я видел, используя FormBuilder, предлагается подписаться на valueChanges поля ввода, в то же время отправляя по трубам debounceTime и distinctUntilChanged.

this.threadForm.get('body').valueChanges.pipe(
            debounceTime(500),
            distinctUntilChanged(),
            mergeMap(search => this.db.query$(...)`))
      )

Я не могу заставить это работать правильно. Похоже, что он правильно отбрасывает время, но когда он проходит по каналу, он отправляет кратный конечный результат (который должен обрабатывать DifferentUntilChanged). Что я делаю не так?

Вот краткое видео проблемы (я добавил tap, чтобы вы могли видеть, что на веб-странице регистрируется несколько окончательных результатов):

https://streamable.com/h2him

Спасибо!

РЕДАКТИРОВАТЬ: Добавление окружающего кода функция source также запускается при каждом нажатии клавиши, поэтому я думаю, что я создаю несколько наблюдаемых объектов независимо от того, как я отменил. Как я могу добавить логику отладки в этом?

  source: (searchTerm, renderList) => {
    //searchTerm is triggered on every button click
    if (searchTerm.length === 0) {
      renderList(this.mentions, searchTerm)
    } else {
      //are multiple instances of this observable being made??
      this.threadForm.get('body').valueChanges.pipe(
        distinctUntilChanged(),
        debounceTime(500),
        tap(x => console.log(x)),
        switchMap(search => this.db.query$(`user/collection?like=username_${searchTerm}&limit=5`))
      ).subscribe( x => {
        console.log(x)
      });
    }
  },

Ответы [ 2 ]

1 голос
/ 10 апреля 2019

Я почти уверен, что проблема здесь связана с объектом, который valueChanges испускает.Для distinctUntilChanged испускаемый объект отличается, вы можете сначала сопоставить этот объект со значением, которое вам действительно нужно.(Вы также можете передать обратный вызов differentUntilChanged , чтобы контролировать то, что должно быть отличным)

например,

this.threadForm.get('body').valueChanges.pipe(
  debounceTime(500),
  map( (obj) => obj.searchVal ),
  distinctUntilChanged(),
  mergeMap(search => this.db.query$(...)`))
)

, и вы наверняка ищете switchMapсвыше mergeMap

РЕДАКТИРОВАТЬ

Чтобы работать с функцией источника, вы можете использовать тему таким образом.

var searchSubject = new Subject<any>();

source: (searchTerm, renderList) => {
  searchSubject.next({searchTerm, renderList});
}

, чем этотsearchSubject вы подписываетесь только один раз в ngOnInit и отписываетесь в onDestroy функциях.

searchSubject.pipe(
 debounceTime(500),
 distinctUntilChanged(),
 mergeMap(search => this.db.query$(...)`))
)
0 голосов
/ 10 апреля 2019

Попробуйте с этим:

this.threadForm.get('body').valueChanges.pipe(
  debounceTime(1000), 
  distinctUntilChanged()).subscribe(changes => {
  this.db.query$(...)
});
...