非常简单地说,我想在用户停止输入设置的时间后执行查询。我所见过的使用FormBuilder
的每一篇教程都建议在管道valueChanges
和debounceTime
的同时订阅输入字段的distinctUntilChanged
。
this.threadForm.get('body').valueChanges.pipe(
debounceTime(500),
distinctUntilChanged(),
mergeMap(search => this.db.query$(...)`))
)
我无法使它正常工作。它似乎可以正确地消除时间的抖动,但是当它通过管道传输时,它会发送多个最终结果(distinctUntilChanged应该处理)。我在做什么错了?
以下是该问题的快速视频(我添加了tap
,因此您可以看到该网页记录了一些最终结果):
谢谢!
编辑:添加周围的代码 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)
});
}
},
答案 0 :(得分:1)
我非常确定这里的问题与valueChanges
发出的对象有关。由于distinctUntilChanged
发出的对象是不同的,您可能需要首先将此对象映射到实际需要的值。 (您还可以向distinctUntilChanged发送回调,以控制不同的内容)
例如
this.threadForm.get('body').valueChanges.pipe(
debounceTime(500),
map( (obj) => obj.searchVal ),
distinctUntilChanged(),
mergeMap(search => this.db.query$(...)`))
)
您肯定会在switchMap
上寻找mergeMap
编辑
要使用源功能,您可以像这样使用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$(...)`))
)
答案 1 :(得分:0)
尝试一下:
this.threadForm.get('body').valueChanges.pipe(
debounceTime(1000),
distinctUntilChanged()).subscribe(changes => {
this.db.query$(...)
});