我尝试执行多个请求并将各自的结果汇总在一起。
我有一个服装列表,其中可以包含服装项目的 ID。当我调用页面时,我尝试使用 ID 从服务器获取衣服。通过这项服务,我获得了每件衣服的 observable。
如何从这些 observable 中读出数据并在最后合并它们?
然后通过 *ngfor
循环输出合并的数据。如果我在下面的代码中尝试它,订阅功能需要更长的时间,直到数据存在并且其他所有事情都已经执行完毕。所以在 HTML 文件中,数据是未定义的。对不起,我希望我能够澄清我的问题。
PageComponent.ts
:
ngOnInit() {
this.isLoading = true;
this.outfitSub = this.outfitService.outfits.subscribe(outfits => {
this.geladeneOutfits = outfits;
});
}
ionViewWillEnter() {
this.isLoading = true;
this.outfitService.fetchOutfit().subscribe(() => {
this.geladeneOutfits.map(outfit => {
this.kleiderschrankService.getKleidungsstueck(outfit.oberteil1).subscribe(teil => {
this.oberteil1 = teil;
});
if(outfit.oberteil2 != null){
this.kleiderschrankService.getKleidungsstueck(outfit.oberteil2).subscribe(teil => {
this.oberteil2 = teil;
});
}
if(outfit.oberteil3 != null){
this.kleiderschrankService.getKleidungsstueck(outfit.oberteil3).subscribe(teil => {
this.oberteil3 = teil;
});
}
var outfitf = new OutfitKl (
this.oberteil1,
this.oberteil2,
this.oberteil3,
this.unterteil1,
this.unterteil2,
this.schuhe,
this.accessoir1,
this.accessoir2,
outfit.imageUrl
)
this.gezeigteOutfits.push(outfitf);
});
this.isLoading = false
});
}
PageComponent.html
:
<ion-grid *ngIf="!isLoading && gezeigteOutfits.length > 0">
<ion-row no-padding>
<ion-col>
<div>
<ion-card *ngFor="let outfit of gezeigteOutfits">
<img [src]="outfit.imageUrl" >
<ion-card-header>
<ion-card-subtitle>Kleidungsstuecke</ion-card-subtitle>
<ion-card-title>Oberteile</ion-card-title>
</ion-card-header>
<ion-card-content>
<ion-grid>
<ion-row no-padding>
<ion-col size="4" size-sm="3" offset-sm="2">
<div>
<ion-img [src]="outfit.oberteil1.imageUrl">
</ion-img>
<ion-img [src]="outfit.schuhe.imageUrl"></ion-img>
</div>
</ion-col>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>
</div>
</ion-col>
</ion-row>
</ion-grid>
KleiderschrankService
:
getKleidungsstueck(kleidungsstueckId: string) {
const kleidungsstueckDocs = this.store
.collection("Kleidungsstueck")
.doc(kleidungsstueckId);
return kleidungsstueckDocs.snapshotChanges().pipe(
map((changes) => {
const data = changes.payload.data();
return data;
})
);
}
答案 0 :(得分:1)
combineLatest 应该可以解决问题。
你可以这样使用:
const first$ = this.kleiderschrankService.getKleidungsstueck(outfit.oberteil1);
const second$ = this.kleiderschrankService.getKleidungsstueck(outfit.oberteil2);
const third$ = this.kleiderschrankService.getKleidungsstueck(outfit.oberteil3);
combineLatest(first$, second$, third$).subscribe(([v1, v2, v3]) => {
//call the this.gezeigteOutfits.push(...) part here so it executes after the data has been recieved
});
答案 1 :(得分:0)
我试图提供准确的解决方案,但由于缺乏信息,这是最多的:
ngOnInit() {
this.outfitSub = combineLatest(this.outfitService.outfits, this.outfitService.fetchOutfit()).subscribe(
([geladeneOutfits]) => {
geladeneOutfits.forEach(outfit => {
const subOb = [this.kleiderschrankService.getKleidungsstueck(outfit.oberteil1)];
outfit.oberteil2 && subOb.push(this.kleiderschrankService.getKleidungsstueck(outfit.oberteil2));
outfit.oberteil3 && subOb.push(this.kleiderschrankService.getKleidungsstueck(outfit.oberteil3));
(combineLatest.apply(this, subOb) as Observable<[any, any, any]>)
.subscribe(([ret1, ret2, ret3]) => {})
})
}
);
}
答案 2 :(得分:0)
使用 RxJS 中的 combineLatest 并使用 filter()、tap() 检查数据
combineLatest(
observable1,
observable2,
observable3
).pipe(
filter(data => !!data),
tap(data => console.log(data))
catchError(error => console.log(error))
).subscribe(
[dataFromObs1, dataFromObs2, dataFromObs33] => {
// This will subscribe only if all the observables return data
// Otherwise it will go to catchError
})
// Filter will check if the data is present or not.
// Tap will return the data before subscribing
// catchError ==> Subscription errors are caught in this catchError