redux NgRx -无法从CustomSerializer路由器存储访问多级路由参数

xu3bshqb  于 2023-06-23  发布在  其他
关注(0)|答案(3)|浏览(95)

我有一个路径声明如下:

{
  path: 'app/:userId',
  children: [...AppChildrenRoutes]
}

然后,在AppChildrenRoutes中

{ path: 'feature', component: MainFeatureComponent }

所以,在我的应用程序的某个时候,我可以有localhost:4200/app/123/feature。在这个组件中,通过一些操作,我可以导航到另一条路线,如下所示:

this.router.navigate([
  'app',
  this.userId,
  'feature',
  { search: this.searchFor }
]);

将其视为一个正在逐步改变架构以使用NgRx的大型企业级应用程序。
所以,我遇到了Router Store的问题。我已经设置好了一切,它的工作。
根据路由器商店文档,我写了一个自定义序列化器,它看起来像这样

serialize(routerState: RouterStateSnapshot): RouterStateUrl {
  const { url } = routerState;
  const queryParams = routerState.root.queryParams;

  while (route.firstChild) {
    route = route.firstChild;
  }
  const params = route.params;

  return { url, queryParams, params };
}

我发现,考虑到URI像

localhost:4200/app/123/feature;search=blue

route.params仅返回search参数,而不是同时返回userIdsearch

  • 如何实现一个CustomSerializer,返回路径中的所有params?(在本例中,userIdsearch都是)。
    我尝试过,但失败了,每次迭代while循环,检查是否有一个参数,并将它们添加到一个对象,直到最后一个。好的,好的还是坏的方法?我怎么能做到这一点而不失败?
    谢谢
6pp0gazn

6pp0gazn1#

我也遇到过类似的问题,通过每次循环时扩展params对象解决了这个问题。
我的CustomSerializer现在看起来像这样:

export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> {
serialize(routerState: RouterStateSnapshot): RouterStateUrl {
    let route = routerState.root;

    let params = {};
    while (route.firstChild) {
        params = {
            ...params,
            ...route.params
        };
        route = route.firstChild;
    }

    const {
        url,
        root: { queryParams }
    } = routerState;

    return { url, params, queryParams };
}

}

d6kp6zgx

d6kp6zgx2#

您可以使用选择器来选择任何父/子路由,并且不需要序列化器。您有一个根Route对象,通过创建一个选择器,您可以遍历路由并获取所需的参数。

const selectRouter = createFeatureSelector<XStore,
    fromRouter.RouterReducerState<any>>('router');

export const selectAllRouteParam = (param: string) => createSelector(
    selectRouter,
    (router: RouterReducerState) => {
        let current = router.state.root;

        while (current) {
            if (current.params && current.params[param]) {
                return current.params[param];
            } else {
                current = current.firstChild;
            }
        }
    }
);

在使用时,您可以像这样使用它:

userId$ = this.store.select(selectAllRouteParam('userId'))

聚会迟到了,但我希望将来有人会发现这有帮助。

ocebsuys

ocebsuys3#

实际上稍微修改的版本(没有选择适当的anser)在Angular v16中对我有效。

export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> {
serialize(routerState: RouterStateSnapshot): RouterStateUrl {
    let route = routerState.root;

    let params = {};
    while (true) {
      params = {
        ...params,
        ...route.params,
      };

      route = route.firstChild;
      if (!route) {
        break;
      }
    }

    const {
        url,
        root: { queryParams }
    } = routerState;

    return { url, params, queryParams };
}

相关问题