Angular 以角度异步加载带有对象的图像

Angular 以角度异步加载带有对象的图像,angular,image,asynchronous,subject,replay,Angular,Image,Asynchronous,Subject,Replay,在我的web应用程序中,用户可以在一种表单中创建对象(其中一个字段是image),并在另一种表单中创建对象集(通过从列表中选择数量)。第三个组件显示所有集合的列表。因为每个非集合对象都有自己的图像,并且可以是多个集合的一部分,所以我偶然发现了一个问题。在我的集合列表中,我不想多次加载同一个图像。我想出了这样的办法: export class SetListComponent implements OnInit { private sets: ObjectSet[]; images

在我的web应用程序中,用户可以在一种表单中创建对象(其中一个字段是image),并在另一种表单中创建对象集(通过从列表中选择数量)。第三个组件显示所有集合的列表。因为每个非集合对象都有自己的图像,并且可以是多个集合的一部分,所以我偶然发现了一个问题。在我的集合列表中,我不想多次加载同一个图像。我想出了这样的办法:

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>