angular - 使用 typeahead ngx-bootstrap 合并两个调用并显示结果?
问题描述
我将首先向您展示工作代码:
<input [formControl]="search"
[typeahead]="suggestions"
typeaheadOptionField="name"
(typeaheadOnSelect)="onSelectedDriver($event)">
ngOnInit(){
public autocompleteValue() {
this.search.valueChanges.subscribe(
(selectedValue) => {
this.searchVal(selectedValue)
}
);
}
}
public searchVal(val: string) {
this.suggestions = (new Observable((observer: Observer<string>) => {
observer.next(val);
})).pipe(
switchMap((query: string) => {
if (query) {
switch (this.serverApi) {
case 'Driver':
return this.getAllDrivers(query);
default:
break;
}
}
return of([]);
})
);
}
和:
getAllDrivers(query: string) {
return this.accountsService.getDrivers(query)
.pipe(
map((data: any) => {
data.body?.forEach((driver: IDriver) => {
driver.name = `${driver.firstName} ${driver.lastName}`
});
return data.body || [];
}),
tap(() => noop, err => {
this.errorMessage = err && err.message || 'Something goes wrong';
})
)
}
这行得通。
但我需要扩展功能。
我需要一个扩展来将两个 api 调用合并为一个并返回结果。
我要这样做,但没有用 forkJoin 预先输入..
this.search.valueChanges.subscribe(val => {
let driverLoad = this.service.searchDrivers(val, [{ name: 'name', value: val }]);
let affiliateLoad = this.service.searchAffiliates(val, [{ name: 'name', value: val }])
forkJoin([driverLoad, affiliateLoad, travelAgenciesLoad]).subscribe(resultsOfSearch => {
let driverArr = resultsOfSearch[0].body;
let affiliateArr = resultsOfSearch[1].body;
this.autoCompleteResults = [...driverArr as [], ...affiliateArr as []];
return this.autoCompleteResults
})
});
我现在不知道是否适合这个工作。
我如何结合它并返回结果?
解决方案
分叉加入
forkJoin 仅在所有源 observables 完成时才发出一个值。因此 - 它可能不适合您的情况。
等待 Observables完成,然后组合它们发出的最后一个值;如果传递了一个空数组,则立即完成。
在您的代码中,在可观察的 driverLoad、affiliateLoad 和 travelAgenciesLoad 都完成之前,forkJoin 不会发出值。
结合最新
如果你的三个 Observable 是连续的数据流,需要在它们完成之前进行组合,一个更好的操作符是 combineLatest:
每当任何输入 Observable 发出一个值时,它都会使用来自所有输入的最新值计算一个公式,然后发出该公式的输出。
//Define observables before subscribing to valueChanges
let driverLoad = this.service.searchDrivers(val, [{ name: 'name', value: val }]);
let affiliateLoad = this.service.searchAffiliates(val, [{ name: 'name', value: val }])
let combinationObservable$: Observable<any>;
// when valueChanges emits a value, find the latest emitted value from driverLoad,
// affiliateLoad, and travelAgenciesLoad
this.search.valueChanges.subscribe(val => {
combinationObservable$ = combineLatest([driverLoad, affiliateLoad, travelAgenciesLoad]);
}
//subscribe to combination Observable outside of the valueChanges subscription
combinationObservable$.subscribe(value => {
console.log(value);
this.autoCompleteResults = value;
});
这是我使用combineLatest操作符模拟你的 observables 的 StackBlitz。
推荐阅读
- flutter - 无法访问“com.ex.app.MainActivity”的超类型“android.arch.lifecycle.LifecycleOwner”
- python - 刷新数据后如何从现有工作簿创建新的 Excel 工作簿
- python - 如何评估 sympy 分段式表达式,以便轻松获得仅数字输出?
- r - 使用 ggplot Boxplot 按年份绘制多个分布
- python - 如何根据条件用另一个列表中的元素替换列表中的某个元素
- wordpress - Elementor WordPress 插件上的 Ajax 调用
- asynchronous - Kotlin:具有 Suspend Function 返回类型的高阶函数
- ios - 缩小后折线开始消失
- flutter - 处理异常 HTTP 请求颤动
- amazon-web-services - AWS S3 PutBucketLifecycleConfiguration 上的 MalformedXML 错误