Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Rxjs构建Angular存储_Angular_Rxjs_Ngrx_Store_Ngrx Store - Fatal编程技术网

使用Rxjs构建Angular存储

使用Rxjs构建Angular存储,angular,rxjs,ngrx,store,ngrx-store,Angular,Rxjs,Ngrx,Store,Ngrx Store,我有一个Angular应用程序,我想在其中为聊天对象创建一个自定义存储 (代码沙盒:) 注意:我知道有像ngrx这样的工具,但这是一个更大项目的一部分,我更愿意使用这个定制实现,以便更好地了解商店的行为 上下文 使其快速高效的想法是在存储中包含两种类型的记录: 带有key=chat id和value=chat object 用于按groupId对聊天进行分组的索引(作为映射),其中key=groupId和value=chatId 所以我有这个接口定义: 导出接口模型{ 聊天:地图; chat

我有一个Angular应用程序,我想在其中为聊天对象创建一个自定义存储

代码沙盒:

注意:我知道有像ngrx这样的工具,但这是一个更大项目的一部分,我更愿意使用这个定制实现,以便更好地了解商店的行为

上下文 使其快速高效的想法是在存储中包含两种类型的记录:

  • 带有
    key=chat id
    value=chat object
  • 用于按groupId对聊天进行分组的索引(作为映射),其中
    key=groupId
    value=chatId
所以我有这个接口定义:

导出接口模型{
聊天:地图;
chatsByGroup:Map;
}
将聊天对象保存到应用商店时,应发生两件事:

  • 聊天对象保存到存储
    chats
  • 聊天id保存到相应groupId中的store
    chatsByGroup
问题 从组中获取聊天对象不起作用。我做了以下工作:

  • 使用groupId从应用商店
    chatsByGroup
    获取聊天ID列表
  • 对于每个聊天id,从商店
    chats
代码:

getGroupChats$(groupId:number):可观察{
返回此。\u store.select(“chatsByGroup”).pipe(
map((chatsByGroup)=>chatsByGroup.get(groupId)| |[]),
开关映射((ID)=>{
如果(!ids | |!ids.length){
归还([]);
}
const chatsList$:Observable[]=ids.map((id)=>
此.u store.select(“chats”).pipe(映射((chats)=>chats.get(id)))
);
返回forkJoin([…chatsList$])。管道(
地图((列表)=>{
返回([]作为聊天[]).concat(…列表);
})
);
}),
共享重播(1)
);
}
调试此代码时,它到达带有
return forkJoin
的行,ids有聊天列表,但它从未到达
map((list)=>{
的行,因此应用程序不显示聊天列表

任何帮助都将不胜感激,谢谢

当任何一个可观察到的东西完成而没有发出任何值时, forkJoin也将在此时完成,并且不会发出 任何事

这是从。我的猜测是,传递给
forkJoin
的一个可观察对象完成而不发出任何东西,因此
forkJoin
立即完成而不发出任何东西

尝试使用
defaultIfEmpty
操作符以确保这种情况不会发生。我建议这样做:

const chatsList$: Observable<Chat>[] = ids.map((id) =>
  this._store.select("chats").pipe(map((chats) => chats.get(id))),
  defaultIfEmpty(null),
);


最后,如果您不想使用
take(1)
,我的意思是,只要观察对象发出值,您就想订阅它,您可能想使用
combinelatetest
而不是
forkJoin
。这是因为
forkJoin
等待完成以发出某些内容,而
combinelatetest
将发出所提供观察对象的最新值vables.

谢谢!它起作用了!而且,如果我想监听每个聊天对象的更改,我不应该使用
take(1)
,对吗?@adrisons是的,
take(1)
只传递一个值,然后完成。
const chatsList$: Observable<Chat>[] = ids.map((id) =>
  this._store.select("chats").pipe(map((chats) => chats.get(id))),
  take(1),
  defaultIfEmpty(null),
);