javascript - double combineLatest 不发出更新
问题描述
在我的项目中,人们创建、加入、添加书签或组织了一些活动。我已经阅读了很多这些问题。但是大部分代码都不那么复杂,或者人们忘记订阅了......
我想获取某个时间段内的所有活动,然后添加创建者信息(名称、图像等)并添加布尔值(如果检索这些活动的用户已加入/添加书签/组织了此活动)。我之前使用的代码将提供实时更新(例如,我通过将我的 userId 添加到参与者数组中来加入活动,并且 activity.joined 将更新为 true)。
以前的代码:
public getActivities(user: UserProfileModel): Observable<Array<ActivityModel>> {
const now: number = moment().startOf('day').unix();
const later: number = moment().startOf('day').add(30, 'day').unix();
return this.afs.collection<ActivityModel>(`cities/${user.city.id}/activities`, ref => ref
.where('datetime', '>=', now)
.where('datetime', '<=', later))
.valueChanges({ idField: 'id' })
.pipe(
map(activities => activities.map(activity => {
const bookmarked = activity.bookmarkers ? activity.bookmarkers.includes(user.uid) : false;
const joined = activity.participants ? activity.participants.includes(user.uid) : false;
const organized = activity.organizers ? activity.organizers.includes(user.uid) : false;
return { bookmarked, joined, organized, ...activity } as ActivityModel;
}))
);
}
我想将创建者添加为可观察对象,以便显示他们的名称或个人资料图片的最新更改。但是随着这个代码的改变,我的 getActivities 不再发出任何更新......
我的新代码:
public getActivities(user: UserProfileModel): Observable<Array<CombinedActivityCreatorModel>> {
const now: number = moment().startOf('day').unix();
const later: number = moment().startOf('day').add(30, 'day').unix();
return this.afs.collection<ActivityModel>(`cities/${user.city.id}/activities`, ref => ref
.where('datetime', '>=', now)
.where('datetime', '<=', later))
.valueChanges({ idField: 'id' })
.pipe(
concatMap(activities => {
const completeActivityData = activities.map(activity => {
const activityCreator: Observable<UserProfileModel> = this.getCreator(activity.creator);
const bookmarked = activity.bookmarkers ? activity.bookmarkers.includes(user.uid) : false;
const joined = activity.participants ? activity.participants.includes(user.uid) : false;
const organized = activity.organizers ? activity.organizers.includes(user.uid) : false;
return combineLatest([
of({ bookmarked, joined, organized, ...activity }),
activityCreator
]).pipe(
map(([activityData, creatorObject]: [ActivityModel, UserProfileModel]) => {
return {
...activityData,
creatorObject: creatorObject
} as CombinedActivityCreatorModel;
})
);
});
return combineLatest(completeActivityData);
})
);
}
代码变得有点复杂,我自己看不到解决方案。有人可以提供一些帮助吗?
解决方案
看起来其中一个activityCreator
没有发出值,combineLatest 要求所有可观察对象至少发出一次。
我建议您调试activityCreator
行为方式。如果它不发射很好,你有两个选择:startWith
为初始发射设置一个值,或者defaultIfEmpty
,如果流将在没有任何发射的情况下关闭,它就会发射。
activityCreator = this.getCreator(activity.creator).pipe(
// startWith(null), // for example if you want to trigger combineLatest.
// defaultIfEmpty(null), // in case of an empty stream.
);
另一件事是concatMap
它需要一个 observable 来完成,然后它才会切换到下一个,也许mergeMap
或者switchMap
更适合这里。
尝试下面的代码并将其输出添加到注释中。谢谢。
const activityCreator: Observable<UserProfileModel> = this.getCreator(activity.creator).pipe(
tap(
() => console.log('getCreator:emit'),
() => console.log('getCreator:error'),
() => console.log('getCreator:completed'),
),
);
推荐阅读
- git - 如何更新本地 Git 源与上游设置?
- r - 使用 && 和/或 || 时遇到问题 并重新编程 NthRoot 函数
- c++ - dyld 没有加载 Ogre 库
- python - 我怎么知道什么时候在 self 之后提出论点?
- html - 在 Bootstrap 3.3.7 .table-responsive 中,有没有办法限制一个单元格的宽度并只截断其中的文本?
- three.js - 渲染新的 ThreeJS 场景时引用现有的 WebGL 深度缓冲区
- python - Pythonic 构造 if 语句以更改变量值的方法?
- javascript - 表格中的多个闪烁文本
- angular - ngrx 商店选择仅订阅特定操作
- pandas - 如何处理无法从 pathlib 读取类型“WindowsPath”的熊猫?