【发布时间】:2020-05-26 07:37:26
【问题描述】:
在我的 Angular (9) 项目中,我使用 HttpClient 从 Rest-API 获取一些值。我在不同的地方订阅它(主要是使用async 管道,不是直接但无论如何)。为了使其多播,我将 HTTP 服务的结果“包装”在 BahaviorSubject 中:
const loadingDog = new BehaviorSubject<Dog|boolean>(true);
const subscription = this.getDogFromHttpClient(dogName)
.pipe(map((dog: Dog|boolean) => this.someProecessing(dog)))
.subscribe(loadingDog);
return loadingDog;
我猜我也可以使用share。
狗永远不会改变。因此,为避免对静态内容的重复调用,请将 loadingDog-Subjects 存储在一个数组中,如果 dog 已被提取,则从数组中返回存储的主题。
public dogs: BehaviorSubject<Dog|boolean>[] = [];
public getDog(name: string): BehaviorSubject<Dog|boolean> {
if (isDefined(this.dogs[dogName])) {
return this.dogs[dogName];
}
const loadingDog = new BehaviorSubject<Dog|boolean>(true);
const subscription = this.http
.get<Dog>(`https://dog.ceo/api/breed/${dogName}/images`)
.pipe(map((dog: Dog|boolean) => this.someProcessing(dog)))
.subscribe(loadingDog);
this.dogs[dogName] = loadingDog;
return loadingDog;
}
在不同的组件中我是这样使用它的:
ngOnInit(): void {
this.useMeInTemplate$ = dogService.getDog('akita').asObservable();
}
因此组件可以决定是否要显示加载标志,或者(在大多数情况下)是否已满足 observable 内容。工作正常。我在许多组件中展示了同一只狗。每个订阅至少触发一次,触发狗的内容,或者如果非常快,触发两次,带有加载状态(在我的示例中为true),然后是内容。
但是如果我以后想创建一个新的并重新使用 observable,它就行不通了。原因似乎是,HttpClient 在某一时刻完成了 Observable,因此包装 BehaviorSubject 也完成了。
I have created an example on Stackblitz,我将所有内容都放在一个组件中。点击 div 看它不工作;)
我想,我对 httpClient 的包装可能做错了。或者我可能对如何“缓存”httpResults 有更大的概念误解?或者我可以并且必须避免完成主题吗?任何帮助表示赞赏!
【问题讨论】: