angular - 订阅 FormBuilder valueChanges 时,使用 debounceTime 和 distinctUntilChanged 不起作用

标签 angular rxjs angular-reactive-forms

非常简单地说,我想在用户停止输入一段时间后执行查询。我看到的每个使用 FormBuilder 的教程都建议订阅输入字段的 valueChanges,同时管道 debounceTimedistinctUntilChanged .

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

我无法让它正常工作。它似乎可以正确地对时间进行去抖动,但是当它通过管道传输时,它会发送多个最终结果(distinctUntilChanged 应该处理)。我做错了什么?

这是问题的快速视频(我添加了一个 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)
      });
    }
  },

最佳答案

我很确定这里的问题与 valueChanges 发出的对象有关。对于 distinctUntilChanged 发出的对象是不同的,您可能希望首先将此对象映射到您实际需要的值。 (您也可以将回调传递给 distinctUntilChanged 以控制不同的内容)

例如

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

而且您肯定正在寻找 switchMap 而不是 mergeMap

编辑

为了使用 source 函数,您可以像这样使用 Subject。

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$(...)`))
)

关于angular - 订阅 FormBuilder valueChanges 时,使用 debounceTime 和 distinctUntilChanged 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55609210/

相关文章:

Angular 失去了最重要的东西,绑定(bind)?

angular - 喷油器错误 "Provider parse errors: Cannot instantiate cyclic dependency!"

angular 6 "ExpressionChangedAfterItHasBeenCheckedError" react 形式动态表单验证添加和删除

angular - 移动目标元素时不会触发点击处理程序

javascript - Angular2 RC1 - 如何取消绑定(bind)窗口事件?

angular - 如何在带有Angular的Electron中的新窗口中打开component.html?

javascript - RxJS:如何在传递下一个有效值之前进行一些清理?

javascript - 为什么我们需要返回一个流而不是直接调度一个值?

javascript - Angular4 - 嵌套的 Http 调用

angular - 使用 FormBuilder 创建禁用的表单组