您的伪代码已完成大部分工作。您所需要的只是搜索键的初始值(我使用了 null,在此实现中空字符串也可以使用)。然后你可以选择切换到什么。
data$: Observable<someData[]>();
searchKeyChanged: Subject<string>();
ngOnInit() {
this.data$ = searchKeyChanged.pipe(
startWith(null),
switchMap(searchKey =>
searchKey != null && searchKey?.length > 0 ?
this.dataService.getDataBySearchKey(searchKey) :
this.dataService.getAllData()
)
);
}
这也是 switchMap 的理想用例,因为如果用户继续输入并且新的 searchKeys 进入,飞行中的服务调用将在中途被取消。
顺便说一句:去抖动很好
如果用户可以快速连续更改 searchKeys,我建议使用 debounce 来平滑用户体验。
ngOnInit() {
this.data$ = searchKeyChanged.pipe(
debounceTime(500),
startWith(null),
switchMap(searchKey =>
searchKey != null && searchKey?.length > 0 ?
this.dataService.getDataBySearchKey(searchKey) :
this.dataService.getAllData()
)
);
}
如果用户停止 searchKeyChanged 触发半秒,这将进行新的服务调用。这意味着 data$ 不会那么卡顿。这也是用户停止片刻然后期待结果的通常节奏。
如果您的服务调用完成速度很慢,但可以取消(例如,它们不是转换的承诺),那么我会在服务调用之后去抖动。这需要更多的计算量,但结果应该比之前的 debounce 快 500 毫秒。
ngOnInit() {
this.data$ = searchKeyChanged.pipe(
startWith(null),
switchMap(searchKey =>
searchKey != null && searchKey?.length > 0 ?
this.dataService.getDataBySearchKey(searchKey) :
this.dataService.getAllData()
),
debounceTime(500)
);
}
当然,您可以更改时间或使用 RxJS 的其他去抖动运算符之一