将查询参数与@ngrx / router-store合并

时间:2018-03-06 07:28:20

标签: angular typescript rxjs ngrx ngrx-effects

我在我的Angular 2+应用程序中使用@ ngrx / router-store并尝试在url的查询参数中编码某些对象。具体来说,每次我在查询参数中编码一个对象时,我想将它与已经存在的查询参数合并。为此,我根据the documentation为路由器商店写了以下副作用:

@Injectable()
export class RouterEffects {
  @Effect({ dispatch: false })
  navigate$ = this.actions$.pipe(
    ofType(RouterActions.GO),
    map((action: RouterActions.Go) => action.payload),
    tap(({ path, query: queryParams, extras}) => {
      this.router.navigate(path, { queryParams,  queryParamsHandling: "merge", ...extras }))
    })
}

然后,为了添加新的查询参数,我可以将它们分派到路由器存储:

store.dispatch(new RouterActions.Go({[], objectToEncode}));

除非快速连续调度多个对象(例如,首次加载应用程序时),否则此工作正常。在这种情况下,副作用将在前一个导航完成之前开始下一个导航,这意味着每个后续导航的查询参数将覆盖上一个导航的查询参数,因此只有最后一个对象将在最终URL中进行编码。

有没有办法防止副作用处理下一个GO动作,直到上一个导航完成?我尝试使用来自商店的查询参数压缩动作,但是当被编码的对象已经在url中,阻止了商店的发布。

1 个答案:

答案 0 :(得分:1)

正如@bygrace所指出的,扫描操作员可以解决问题。这是修改为使用扫描运算符的原始代码:

@Injectable()
export class RouterEffects {
  @Effect({ dispatch: false })
  navigate$ = this.actions$.pipe(
    ofType(RouterActions.GO),
    map((action: RouterActions.Go) => action.payload),
    scan((currentRoute, {path, query: queryParams, extras}) => {
      const nextQueryParams = Object.assign({}, currentRoute.query, queryParams);
      return {path, query: nextQueryParams, extras};
    }, {path: [], query: {}, extras: {}}),
    tap(({ path, query: queryParams, extras}) => {
      this.router.navigate(path, { queryParams,  queryParamsHandling: "merge", ...extras }))
    })
}