如何在 Angular/RxJS 中合并两个 observable?

Posted

技术标签:

【中文标题】如何在 Angular/RxJS 中合并两个 observable?【英文标题】:How to merge two observables in Angular/RxJS? 【发布时间】: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 进行尝试,但无法针对我的用例进行调整.. 【参考方案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* 调用以任意方式显示您的数据。

【讨论】:

它适用于这种方法:),非常感谢:)。

以上是关于如何在 Angular/RxJS 中合并两个 observable?的主要内容,如果未能解决你的问题,请参考以下文章

Angular/RxJS 6:如何防止重复的 HTTP 请求?

Angular 6 / Rxjs - 如何基础:observables 成功,错误,最后

Angular/rxjs:为啥我不必再导入 toPromise 了? [关闭]

Angular + RxJS:使用 takeUntil 与简单取消订阅?

Angular/RxJS:带有可观察对象的嵌套服务调用

Angular RXJS Observables或Subjects在内部传递数字