【问题标题】:How to merge two observables in Angular/RxJS?如何在 Angular/RxJS 中合并两个 observable?
【发布时间】:2021-02-02 08:34:33
【问题描述】:

在我的服务中,我有这些方法:

  getMap(): any {
    return this.http.get(`someURL`);
  }

  getAssets(): any {
    return this.http.get(`someURL`);
  }

在我的组件中,我这样使用它们:

  ngOnInit() {
    this.myService.getMap().subscribe(data => {
      this.map = data; // Returns ["map-1.svg", "map-0.svg"]
    });

    this.systemMapService.getAssets().subscribe(data =>  {
        this.assets = data; // Returns ["map-mapping-0.json", "map-mapping-1.json"]
    });
  }

在我的模板中,我想这样使用它:

<mat-tab-group mat-align-tabs="end">
  <div *ngFor="let item of assets; let i = index">
    <mat-tab label="{{i}}">
      <div class="container">
        <div class="map">
          <img id="img_equipment" [src]="apiUrl + '/path/to/svg/' + item">
          <a *ngFor="let link of map"
             title="{{ link.title }}"
             class="ink"
             [ngStyle]="{ left: link.left, top: link.top, width: link.width }">
          </a>
        </div>
      </div>
    </mat-tab>
  </div>
</mat-tab-group>

我在代码中将调用的返回值作为 cmets 提供。

例如,文件 map-0.svg 应使用此 JSON 作为映射 map-mapping-0.json。文件map-1.svg 然后依次是这个JSON文件map-mapping-1.json

.. 调用返回的数组是否必须进行排序才能正常工作?因为不幸的是,它们目前正被后端未排序地返回。

【问题讨论】:

  • 这能回答你的问题吗? How to 'wait' for two observables in RxJS
  • “是否必须对调用返回的数组进行排序才能使其工作” - 你告诉我们,你想通过索引匹配它们吗(在这种情况下是) 还是你可以按价值来做(在这种情况下不一定)?
  • @jonrsharpe 正如我的描述中提到的,文件 map-0.svg 应该使用 map-mapping-0.json。因此,文件名末尾的数字至关重要。每个 .svg 都有一个可以使用的特定 JSON 文件。
  • 你可能想看看 rxjs 运算符combineLatest
  • 我目前正在使用 combineLatest 进行尝试,但无法针对我的用例进行调整..

标签: angular typescript rxjs angular-material rxjs-observables


【解决方案1】:

从您的模板和描述来看,您的数据应该采用什么形状才能让您最轻松地完成此操作并不完全清楚。无论如何,我的直觉是转换您的数据,直到您的模板轻松使用它,然后使用 Angular 的异步管道。

// I'm making this an array of strings tuples, but it can 
// be whatever best serves your purpose
displayData = Observable<Array<[string, string]>>;
ngOnInit() {
 
  this.displayData = forkJoin({
    mapData: this.myService.getMap(),
    mapAssets: this.systemMapService.getAssets()
  }).pipe(
    map(({mapData, mapAssets}) => {
      const formattedData = mapData.map(mapInstance => {
          // You're going to have to define this function yourself
          // to effective organsize/sort/whatever your data. 
          const assetInstance = this.extractMapAsset(mapAssets, mapInstance);
          return [mapInstance, assetInstance];
      });
      return formattedData;
    })
  );
}

// In template
<div *ngFor='let tupleData of displayData | async'>
    The map is called {{tupleData[0]}} 
    and its assetJson is called {{tupleData[1]}}
</div>

这是一个非常简化的示例,但它得到了基本结构。您加入并格式化您的数据,然后将其显示在您的视图中。在此示例中,它只是一个字符串元组,但它可以是任何您查看的内容,可以嵌套 ngFor* 调用以任意方式显示您的数据。

【讨论】:

  • 它适用于这种方法:),非常感谢:)。
猜你喜欢
  • 2020-09-01
  • 1970-01-01
  • 2021-09-26
  • 2019-12-25
  • 1970-01-01
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多