更新NGRX / Redux存储对象属性

时间:2018-05-14 16:25:07

标签: angular redux ngrx ngrx-effects

我的Angular应用程序中的场景是,用户点击" ShowDetails"这应该显示一个表单,其中包含我在启动时已加载的所选项目的详细信息,但不显示详细信息,我不想加载所有详细信息OnInit。

我能够成功发送一个动作,但是我想要一个应该获得id的效果(我假设从商店中),进行一次http调用,获取该项目的详细信息并将其添加为主项目的属性,以便后续调用不再返回服务。我可以做所有这些。

我的问题是我不知道如何在不改变商店中的原始对象的情况下更新商店中主对象的属性(我知道我不应该这样做)因此后续调用不会调用再次服务。或者如何更新效果中的属性,然后才能进入Reducer进行最终处理?理想情况下,我希望在细节返回之前显示一个带有加载图标的空表单页面。

1 个答案:

答案 0 :(得分:1)

您的效果需要选择所请求的数据是否已经存储在商店中,并且只有在不存在时,它才会启动AJAX请求来获取它。在这两种情况下,一旦数据准备就绪,就可以发送“数据就绪”动作。

以下是我过去的做法:

export class MyEffects {
  constructor(private store$: Store<fromStore.AppState>,
    private action$: Actions,
    private backend: MyService,
  ) { }

  @Effect()
  fetchData$ = this.action$.ofType<fromActions.FetchDataAction>(fromActions.FETCHDATA).pipe(
    withLatestFrom(this.store$.select(x => x.main.cacheMap)),
    switchMap(([action, cacheMap]) => this.fetchData(action.id, cacheMap)),
    map(r => r new fromActions.DataReadyAction(r)),
  );

  fetchData(id: string, cacheMap: { [key: string]: Item }): Observable<Item> {
    if (!cacheMap[id]) {
      return this.backend.getData(id);
    } else {
      return of({ ...cacheMap[id] });
    }
  }
}

请注意以下几点:

  • 效果类构造函数将商店注入其中。
  • 效果本身使用withLatestFrom获取州的最新副本。
  • fetchData函数选择是发送AJAX请求还是根据作为商店一部分的cacheMap变量中是否存在请求的密钥立即返回。

DataReady操作减少时,新项目将被放置在状态的缓存映射中,以便后续的FetchData操作不会重新请求它。