我使用angularFirestore在Firebase上进行查询,并希望使用DocumentReference联接来自多个文档的数据。
管道中的第一个运算符映射返回IOrderModelTable数组,第二个运算符,即switchMap遍历数组,对每个元素使用每个元素中包含的ID来查询其他表中的数据。
问题在于,由于带地图的操作符,我在swithMap中获得了一个可观察的数组。如何获取IOrderModelTable的数组,然后返回该数组的可观察值。
代码是:
getDataTableOperatorsFromDB(): Observable<IOrderModelTable[]> {
const observable = this.tableOperatorsCollectionsRef.snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data() as IOrdersModelDatabase;
const id = a.payload.doc.id;
data.ot = id;
return data;
});
}),
switchMap(data => {
const result = data.map(element => {
return this.afs.collection('Orders/').doc(element.orderNumberReference.id).valueChanges().pipe(map(order => {
return {
otNumber: element.ot,
clientName: '',
clientReference: order.clientReference,
id: element.orderNumberReference,
};
}));
});
// Result must be an IOrderModelTable[] but is a Observable<IOrderModelTable>[]
return of(result);
})
);
答案 0 :(得分:1)
您可以使用to Array运算符将流转换为数组,但要确保流将结束。 诀窍是选择正确的流。
对于您的问题,自然源将是您的第一个电话收到的列表。用一种示意性的方式,我可以得到一个id列表,然后将其转换为增强信息列表:
第一个输入...snapshopChanges()
:
---- [[A,B,C] ------>
每个元素都通过...valueChanges()
进行转换:
-------呼叫A ------------- DataA -------->
-------呼叫B ------------------------ DataB ----->
-------呼叫C -------------------- DataC ----->
然后使用toArray()
简化为:
------------------------------------------------ [ DataA,DataC,DataB] -------->
代码:
getDataTableOperatorsFromDB(): Observable<IOrderModelTable[]> { {
return this.tableOperatorsCollectionsRef.snapshotChanges()
.pipe(
map(actions => {
from(data).pipe(
map(action => {
const data = a.payload.doc.data() as IOrdersModelDatabase;
const id = a.payload.doc.id;
data.ot = id;
return data;
}),
mergeMap(element => {
return this.afs.collection('Orders/').doc(element.orderNumberReference.id).valueChanges().pipe(
map(order => {
return {
otNumber: element.ot,
clientName: '',
clientReference: order.clientReference,
id: element.orderNumberReference,
};
})
);
}),
toArray()
);
})
)
}
重要提示:我将switchMap
替换为mergeMap
,否则一些信息可能会被丢弃。
答案 1 :(得分:1)
@madjaoue 没错,在这种情况下,mergeMap是正确的运算符,因为对于每个发出的事件,使用switchMap都会破坏内部的可观察对象,因此在订阅中,您只会得到发出的最终事件,即最后一行。这种可观察的生命周期长,从不完整,因此还请使用运算符take来指定包含文档列表的数组的操作长度。
非常感谢您的帮助。 :D
getDataTableOperatorsFromDB(): Observable<IOrderModelTable[]> {
const observable = this.tableOperatorsCollectionsRef.snapshotChanges().pipe(
switchMap(actions => {
return from(actions).pipe(
mergeMap(action => {
console.log(action);
const data = action.payload.doc.data() as IOrdersModelDatabase;
const otNumber = action.payload.doc.id;
return this.afs.collection('Orders/').doc(data.orderNumberReference.id).valueChanges().pipe(map(order => {
return {
otNumber: otNumber,
clientName: '',
clientReference: order.clientReference,
id: data.orderNumberReference,
};
}));
}),
mergeMap(order => {
console.log(order);
return this.afs.collection('Clients/').doc(order.clientReference.id).valueChanges().pipe(map(client => {
return {
otNumber: order.otNumber,
clientName: client.name,
clientReference: order.clientReference,
id: order.id,
};
}));
}),
take(actions.length),
toArray(),
tap(console.log),
);
}),