Angular 以角度异步加载带有对象的图像
在我的web应用程序中,用户可以在一种表单中创建对象(其中一个字段是image),并在另一种表单中创建对象集(通过从列表中选择数量)。第三个组件显示所有集合的列表。因为每个非集合对象都有自己的图像,并且可以是多个集合的一部分,所以我偶然发现了一个问题。在我的集合列表中,我不想多次加载同一个图像。我想出了这样的办法:Angular 以角度异步加载带有对象的图像,angular,image,asynchronous,subject,replay,Angular,Image,Asynchronous,Subject,Replay,在我的web应用程序中,用户可以在一种表单中创建对象(其中一个字段是image),并在另一种表单中创建对象集(通过从列表中选择数量)。第三个组件显示所有集合的列表。因为每个非集合对象都有自己的图像,并且可以是多个集合的一部分,所以我偶然发现了一个问题。在我的集合列表中,我不想多次加载同一个图像。我想出了这样的办法: export class SetListComponent implements OnInit { private sets: ObjectSet[]; images
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);
}
}
我决定使用ReplaySubject,因为我了解到它可以被多个订阅者使用,并且当新订阅者到来时,它总是返回最后一个值(在本例中,只有最后一个值)。我认为我的HTML将调用方法getObjectImage
,并订阅ReplaySubject
。因为console.log('getObjectImage:'+objectId)代码>我发现这个方法被调用的次数比我列表中的对象要多。
我的问题是:
- 每个对象多次调用方法可以吗
- 在这种情况下使用ReplaySubject是件好事吗
<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>