在我的网络应用程序中,用户可以以一种形式创建对象(其中一个字段是图像)并以另一种形式制作它们的集合(通过从列表中选择它们的数量)。第三个组件显示所有集合的列表。由于每个非集合对象都有自己的图像并且可以是多个集合的一部分,所以我偶然发现了一个问题。在我的集合列表中,我不想多次加载同一个图像。我想出了这样的事情:
export class SetListComponent implements OnInit {
private sets: ObjectSet[];
images: Map<number, ReplaySubject<string>>;
constructor(){
this.image = new Map();
this.sets = [];
}
ngOnInit() {
this.reloadSets();
}
reloadSets() {
this.prizeService.getAllSets().subscribe(prizeSets => {
this.updateImageMap(prizeSets);
this.prizeSets = prizeSets;
})
}
private updateImageMap(sets: ObjectSet[]): void {
sets.map(set => set.elementsList)
.reduce((acc, x) => acc.concat(x), [])
.map(prize => prize.id)
.forEach(objectId => {
if (!this.images.has(objectId)) {
this.images.set(objectId, new ReplaySubject(1));
this.getImageFromAPI(objectId);
}
});
}
private getImageFromAPI(objectId: number) {
const reader = new FileReader();
reader.onload = (e) => {
this.images.get(objectId).next(e.target['result']);
};
this.objectService.getImage(objectId)
.subscribe(blob => {
reader.readAsDataURL(blob);
});
}
getObjectImage(objectId: number): Subject<string> {
console.log('getObjectImage: '+objectId);
return this.images.get(objectId);
}
}
基本上在ngOnInit
重新加载集中,即objectId
添加<objectId, new ReplaySubject(1)>
条目到地图,然后开始从 API 加载图像。有一个小的 HTML 示例:
<mat-expansion-panel *ngFor="let set of objectSets" class="m-2">
<ng-container *ngFor="let obj of set.elementsList">
<mat-list-item>
<h4 mat-line>{{obj.name}}</h4>
<p><img [src]="getObjectImage(obj.id) | async" alt="{{obj.id}}"/></p>
</mat-list-item>
</ng-container>
</mat-expansion-panel>
我决定使用 ReplaySubject 因为我读到它可以被多个订阅者使用,并且当新订阅者到来时它总是返回最后一个值(在这种情况下只有一个最后一个值)。我认为我的 HTML 将调用方法getObjectImage
并订阅ReplaySubject
. 因为console.log('getObjectImage: '+objectId);
我发现这个方法被调用的次数比我列表中的对象要多。我的问题:
- 每个对象多次调用方法是否可以?
- 在这种情况下使用 ReplaySubject 是个好东西吗?