angular - 使用 Rxjs (Angular) 在几个不同的条件下刷新 API 调用
问题描述
所以要画一张图片,这是我当前的代码:
ngOnInit(): void {
this._pbsaAccountSelectorService.selectedAccount$.subscribe((pSelectedAccount) => {
this.getSelectedAccountData(this._pbsaAccountSelectorService.selectedProfile.ProfileId, pSelectedAccount.AccountNumberForRequests);
});
}
getSelectedAccountData(ProfileId: string, AccountNumberForRequests: string) {
if(!this._rewardsService.currentSpend) {
this._rewardsService.getCurrentSpend(ProfileId, AccountNumberForRequests).subscribe((res: any) => {
this._rewardsService.currentSpend = res
})
}
combineLatest([
this._rewardsService.getEnigmaTransactions(AccountNumberForRequests),
this.refresher$,
]).pipe(
map(([val]) => val),
takeUntil(this._pbsaAccountSelectorService.selectedAccount$),
).subscribe(res => {
this.transactionList = res;
this.filteredTransactionList = res;
})
}
预期的行为是每次 selectedAccount$ Subject 发出一个值时,它都会触发 getCurrentSpend 和 getEnigmaTransactions API 调用。但除此之外,我还需要在某些情况下手动触发 getEnigmaTransactions 调用,例如某些过滤条件发生变化时。
为了尝试实现这一点,我将 getEnigmaTransactions 调用放在带有复习主题的 combineLatest 中。
这样做的问题是,如果帐户发生更改,我需要取消现有的 combineLatest,否则它只会进行越来越多的订阅。所以我尝试放置一个 takeUntil ,每次帐户更改时都会取消,但我认为发生的事情是,一旦发出第一个 selectedAccount ,整个事情就会取消并且永远不会再次触发。
诚然,即使这个实现确实有效,我也可能会寻找更优雅的解决方案,因为这似乎是一种糟糕的做事方式。
我怎样才能实现我想要的行为?也许使用 SwitchMap?
解决方案
您永远不应该在 RXJS 中将 subscribe 放入 subscribe 中,您应该将传入的流合并为一个获取数据的流
您应该将应该重新触发获取数据的所有内容放入 observable 中,以使其具有反应性。
combileLatest
使得在任何输入数据发生变化时,switchMap
如果过滤器更改得更快以至于 API 可以返回数据,则将取消先前的请求。
class MyComponent {
readonly selectedAccount$ = new Subject<any>();
readonly filters$ = new Subject<any>();
readonly data$ = combineLatest([
this.selectedAccount$,
this.filters$
]).pipe(
switchMap(([account, filters]) => {
return fetchDataObservable(account, filters);
}),
//shareReplay({ refCount: true, bufferSize: 1 }), // If this observable would be used at multiple places this will prevent fetching data twice
//takeUntil(this.destroy), // If you would use this in other places than template only
);
}
<pre>{{data$ | async | json}}</pre>
推荐阅读
- c++ - 如何将字符串转换为标题大小写?
- python - 使用python迭代批量导入到sql server
- swift - 如何将结构实例转换为数据以使用 GameKit 保存它
- javascript - jsx html标签中的动态变量未更新
- angular - 我们可以在一个应用程序代码中使用 Angular SSR 和 PreRendering 混合吗
- python - tkinter 通过获取输入字段打印值
- python - 找到部分闭合的精明边缘的中间
- oracle - (Oracle)在子查询中使用 WITH 子句
- angular - 使用 angular8 在 api 请求中发送下载的文件
- c - 为什么 BSON 不使用 uint32_t 而不是 int32_t 作为文档长度