发布
社区首页 >问答首页 >循环ID数组并通过可观察的方法获取数据

循环ID数组并通过可观察的方法获取数据
EN

Stack Overflow用户
提问于 2021-04-23 09:54:02
回答 2查看 904关注 0票数 0

我有一个device_ids数组。通过在UI上选择项来动态扩展数组。最初和每次更新数组时,我都需要迭代它并为每个device_id获取数据。G

获取数据基本上是一个数据库请求(对Firestore),它返回一个可观察到的数据。通过使用switchMap,我从其他数据库请求中获取一些数据。

最后,我希望有一个类似于对象/可观测的数组,其中包含我可以订阅的所有数据。我的目标是在HTML中使用角的异步管道。

这是可能的吗(例如用RxJS)?我不知道怎么解决这个..。

这就是我的代码当前的样子:

代码语言:javascript
代码运行次数:0
复制
// Init
devices$: Observable<any;

// Array of device_ids
device_ids = ['a', 'b'];

// Get device data. This will initially be called on page load.
getDeviceItemData(device_ids) {

    // Map / loop device_ids
    device_items.map(device_id => {

        // getDeviceById() returns an Observable
        return this.getDeviceById(device_id).pipe(

        // Switch to request additional information like place and test_standard data
        switchMap(device => {

            const place$ = this.getPlaceById(device['place_id]');
            const test_standard$ = this.getTestStandardById(device['test_standard_id]');

            // Request all data at the same time and combine results via pipe()
            return zip(place$, test_standard$)
                .pipe(map(([place, test_standard]) => ({ device, place, test_standard })));
        })
        ).subscribe(device_data => {
            // Do I need to subscribe here?
            // How to push device_data to my Observable devices$?
            // Is using an Observable the right thing?
        });
    });
}

// Add device
addDevice(device_id) {

    // Add device_id to array
    this.device_ids.push(device_id);

    // Fetch data for changed device_ids array
    getDeviceItemData(this.device_ids);
}

使用异步管道的首选HTML /角代码:

代码语言:javascript
代码运行次数:0
复制
<div *ngFor="device of devices$ | async">{{ device.name }}</div>

谢谢你的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-23 10:28:08

这在rxjs中是绝对可能的。你走在正确的道路上。我对您的getDeviceItemData()方法做了一个小的修改。

一旦id检索到设备信息,就可以使用forkJoin执行两个调用来并行地获取place和test_standard数据,然后映射该数据以返回您需要的对象,其中包含设备、place和test_standard的信息作为可观察的信息。由于我们是在device_ids上映射,所以它将生成一个包含所需对象的可观察的数组,这样您就可以轻松地使用异步管道来连接它们。

请注意:您不必订阅devices$,因为async pipe会自动为您完成此操作。

请参阅以下代码:

代码语言:javascript
代码运行次数:0
复制
  // Init
  devices$: Observable<{ device: any, place: any, test_standard: any }>[];

  // Array of device_ids
  device_ids = ['a', 'b'];

  getDeviceId: (x) => Observable<any>;
  getPlaceById: (x) => Observable<any>;
  getTestStandardById: (x) => Observable<any>;

  getDeviceItemData() {
    this.devices$ = this.device_ids.map((id) =>
      this.getDeviceId(id).pipe(
        switchMap((device) => {
          return forkJoin([
            this.getPlaceById(device['place_id']),
            this.getTestStandardById(device['test_standard_id'])
          ]).pipe(map((y) => ({ device, place: y[0], test_standard: y[1] })));
        })
      )
    );
  }

在你的中,你必须做:

编辑:由于设备$是一个可观察的数组,我们需要迭代单个可观测数据,并对每个可观察的对象应用异步管道。

代码语言:javascript
代码运行次数:0
复制
<div *ngFor="device of devices$">
  <div *ngIf="device | async as device"> 
    <div>{{ device.device.name }}</div>
    <div>{{ device.place}}</div>
    <div>{{ device.test_standard }}</div>
  </div>
</div>
票数 2
EN

Stack Overflow用户

发布于 2021-04-23 10:33:05

使用forkJoin,您可以等待所有可观察到的complete。或者,您可以使用combineLatest,这将为您提供最新的数据组合,每次一个可观察的发射数据。这将导致更多的事件,但不会等待所有事件的完成。

代码语言:javascript
代码运行次数:0
复制
getDeviceItemData(device_ids) {
  const arrayOfObservables = device_ids.map(device_id => {
    return this.getDeviceById(device_id).pipe(...);
  }
  return combineLatest(arrayOfObservables); // Observable<Data[]>
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67227790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档