我有一个device_ids
数组。通过在UI上选择项来动态扩展数组。最初和每次更新数组时,我都需要迭代它并为每个device_id
获取数据。G
获取数据基本上是一个数据库请求(对Firestore),它返回一个可观察到的数据。通过使用switchMap
,我从其他数据库请求中获取一些数据。
最后,我希望有一个类似于对象/可观测的数组,其中包含我可以订阅的所有数据。我的目标是在HTML中使用角的异步管道。
这是可能的吗(例如用RxJS)?我不知道怎么解决这个..。
这就是我的代码当前的样子:
// 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 /角代码:
<div *ngFor="device of devices$ | async">{{ device.name }}</div>
谢谢你的帮助!
发布于 2021-04-23 10:28:08
这在rxjs中是绝对可能的。你走在正确的道路上。我对您的getDeviceItemData()
方法做了一个小的修改。
一旦id检索到设备信息,就可以使用forkJoin
执行两个调用来并行地获取place和test_standard数据,然后映射该数据以返回您需要的对象,其中包含设备、place和test_standard的信息作为可观察的信息。由于我们是在device_ids上映射,所以它将生成一个包含所需对象的可观察的数组,这样您就可以轻松地使用异步管道来连接它们。
请注意:您不必订阅devices$
,因为async pipe
会自动为您完成此操作。
请参阅以下代码:
// 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] })));
})
)
);
}
在你的中,你必须做:
编辑:由于设备$是一个可观察的数组,我们需要迭代单个可观测数据,并对每个可观察的对象应用异步管道。
<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>
发布于 2021-04-23 10:33:05
使用forkJoin
,您可以等待所有可观察到的complete
。或者,您可以使用combineLatest
,这将为您提供最新的数据组合,每次一个可观察的发射数据。这将导致更多的事件,但不会等待所有事件的完成。
getDeviceItemData(device_ids) {
const arrayOfObservables = device_ids.map(device_id => {
return this.getDeviceById(device_id).pipe(...);
}
return combineLatest(arrayOfObservables); // Observable<Data[]>
}
https://stackoverflow.com/questions/67227790
复制相似问题