我正在尝试通过使用两个操作来修改使我可以启动和停止多个Firestore查询的效果。目前,该效果允许我通过侦听效果中的两个独立操作来启动和停止单个Firestore查询。当发生停止动作时,我只是使用switchMap切换到一个空的可观察对象。这样就可以了。
@Effect()
startStopQuery$ = this.actions$.pipe(
ofType(
ActionTypes.START,
ActionTypes.STOP
),
switchMap(action => {
if (action.type === ActionTypes.STOP) {
return of([]);
} else {
return this.afs.collection('collection', ref => {
return ref.where('field', '==', 'x');
}).stateChanges();
}
}),
mergeMap(actions => actions),
map(action => {
return {
type: `[Collection] ${action.type}`,
payload: { id: action.payload.doc.id, ...action.payload.doc.data() }
};
})
);
我实际上想要做的是让多个查询持续进行,我可以通过相同的两个动作来开始和停止,但是这取决于动作有效负载。每次执行新查询时,对其进行修改时,最后一个查询将停止工作。我认为这是因为switchMap
运算符从我观察到的上一个查询切换开了。这是我想出的最好的方法:
@Effect()
startStopQueryById$ = this.actions$.pipe(
ofType(
ActionTypes.START_BY_ID,
ActionTypes.STOP_BY_ID
),
switchMap(action => {
if (action.type === ActionTypes.STOP_BY_ID) {
return of([]);
} else {
return this.afs.collection('collection', ref => {
return ref.where('field', '==', action.id);
}).stateChanges();
}
}),
mergeMap(actions => actions),
map(action => {
return {
type: `[Collection] ${action.type}`,
payload: { id: action.payload.doc.id, ...action.payload.doc.data() }
};
})
);
正如我所说,我认为问题是switchMap
运算符。但这也是我首先要使“停止”工作所依赖的。我似乎还无法提出另一种解决方案,因为我还不太熟悉这种风格。
任何帮助将不胜感激!
答案 0 :(得分:0)
我想出了一个解决方案。我制作了一个将ID映射到firestore statechanges可观察对象的对象。在开始动作中,我使侦听器并将其添加到对象。我确保通过用相应的停止操作用管道takeUntil
来取消订阅。它返回对象中所有可观察对象的merge
,我像以前一样傻傻地做。我还有一个单独的作用,由stop动作触发,以从对象中移除可观察对象。看起来像这样:
queriesById: {[id: string]: Observable<DocumentChangeAction<Element>[]>} = {};
@Effect()
startQuery$ = this.actions$.pipe(
ofType(ActionTypes.START_BY_ID),
switchMap(action => {
this.queriesByPlay[action.pid] = this.afs.collection<Element>('requests', ref => {
return ref.where('field', '==', action.id);
}).stateChanges().pipe(
takeUntil(
this.actions$.pipe(
ofType(ActionTypes.STOP_BY_ID),
filter(cancelAction => action.id === cancelAction.id),
)
)
);
return merge(
Object.values(this.queriesByPlay)
);
}),
mergeMap(actions => actions),
mergeMap(actions => actions),
map(action => {
return {
type: `[Collection] ${action.type}`,
payload: { id: action.payload.doc.id, ...action.payload.doc.data() }
};
})
);
Effect({dispatch: false})
stopQuery$ = this.actions$.pipe(
ofType(ActionTypes.STOP_BY_ID),
map(action => delete this.queriesByPlay[action.id]),
);
这似乎可行,除了难以理解的麻烦之外,没有任何问题。