如果项目不在商店中,则调度操作以获取它

时间:2017-08-02 19:53:04

标签: angular ngrx

我试图找出获取商品的最佳方式,如果它不在商店中。

例如,假设我有一个用户列表,我想获取特定用户。如果该用户不在商店中,我想从数据库中获取他。

下面的代码是最佳实践还是有更好的方法?

const searchedUserId = 'abcdefg'; 
this.selecedUser$ = this.store.select(state => {
   const selectedUserIndex = state.userList.findIndex(searchedUserId)
   if (selectedUserIndex === -1) {
     this.store.dispatch(new UsersActions.FetchUsers(searchedUserId));  
   } else {
     return state.userList[selectedUserIndex]
   }
})

4 个答案:

答案 0 :(得分:2)

创建selector以从商店中获取数据。

Creating a selector

在您的组件中,您需要subscribe到州。

store.select(selectFeatureState).subscribe(state => {
    //Search for the user in the state.
    // If user is not there then dispatch the action
    store.dispatch(ACTION);
});

然后,使用@ngrx / effects

创建Effects

create effects

效果侦听操作,然后调用服务,检索数据并更新商店。

由于商店已经订阅了商店,它将更新该组件。

答案 1 :(得分:1)

const searchedUserId = 'abcdefg';
this.selecedUser$ = this.store.select('userList').pipe(
  map(userList=>{const result = userList.findIndex(item=>item.id===searchedUserId);
  return result === -1 ? {} : result;
  }),
  tap(userList=>{
    if( !userList.hasOwnProperty('id') ) this.store.dispatch(new UsersActions.FetchUsers(searchedUserId));
  })
);

点击不会更改可观察对象,并且当分派的动作将更改状态时,可观察对象将被更新。

使用选择器代替select语句,并注意该操作找不到密钥的情况。

答案 2 :(得分:0)

你需要一名警卫。

  1. 为您的用户详细信息组件(包含ID)定义路由
  2. 为该路线定义防护并将其放入CanActivate
  3. 在警卫中,调度LoadUserDetailsAction(userId)
  4. 当该操作解决时(Guard在加载详细信息时侦听存储)返回true以便显示您的组件
  5. 现在可以安全地在yoir组件中执行store.select(userdetails)

答案 3 :(得分:0)

如果它不在商店中也未获取,则您的应用程序不需要此信息。通常,这种逻辑会进入guardsinitializersresolvers或任何其他逻辑方法中以获取此类数据。

如果我查看您描述的流程,那么为了到达您所谈论的用户页面,我必须单击某些内容以导航到该页面,甚至只是折叠卡片或类似内容。

在事件发生后的这一点上,您的应用程序有几种不同的处理方式,要么发送请求/调度操作,然后使用guard / resolver来获取数据。

在商店内部订阅商店数据并根据商店状态获取更多数据是不好的做法,并且会导致无限循环,调试问题以及找出谁触发了问题。