ngrx/router-store - 路由参数选择器 returns 未为子路由定义

ngrx/router-store - route parameter selector returns undefined for the child route

我设置了这个路由:

const SONGS_ROUTES = [
  {
    path: "songs",
    children: [
      // ...
      {
        path: "edit/:id",
        component: PerformancesComponent, // CHILD ROUTE
      },
      {
        path: "",
        component: PerformancesComponent,
      },
    ],
  },
];

const routes: Routes = [
  {
    path: "",
    component: ConcertsComponent,
    children: [
      {
        path: "edit/:friendlyUrl",
        component: ConcertEditComponent,   // PARENT route
        children: SONGS_ROUTES,
      },
    ],
  },
];

并且我需要能够在树中的每个组件中使用 ngrx 选择器获得 friendlyUrl。所以我定义如下:

export const routerFeatureKey = "router";

export const selectRouterState = createFeatureSelector<
  fromRouter.RouterReducerState
>(routerFeatureKey);

export const {
  selectCurrentRoute, // select the current route
  selectQueryParams, // select the current route query params
  selectQueryParam, // factory function to select a query param
  selectRouteParams, // select the current route params
  selectRouteParam, // factory function to select a route param
  selectRouteData, // select the current route data
  selectUrl, // select the current url
} = fromRouter.getSelectors(selectRouterState);

export const getSelectedConcertFriendlyUrl = selectRouteParam("friendlyUrl");

它确实在 "PARENT" 级组件(路由)上工作。这意味着当用户转到 edit/some-concert 选择器 returns some-concert。但是对于 /edit/some-concert/edit/songs/1(在子组件中)它 returns undefined。我不知道为什么。

routerState: RouterState.MinimalrouterState: RouterState.Full 我都试过了。相同的结果。

我可以尝试哪些新事物?

为了解决这个问题,我创建了自己的选择器:

export const getSelectedConcertFriendlyUrl = createSelector(
  selectUrl,
  (url) => {
    const extractRegex = /\/concerts\/edit\/([a-zA-Z0-9_-]+)\/?.*/gi;
    const matches = extractRegex.exec(url);
    if (matches && matches.length > 1 && matches[1]) {
      return matches[1];
    }
    return undefined;
  }
);

它目前不包括所有边缘情况,所以我会改进它。

然后@brandonroberts 在 Twitter 上友善地回复说:

The selectors for router-store traverse down to the lowest active route in the tree, which is why you won't get that parameter. If you need to all the params in the tree, you need a custom selector.

是的,您必须创建自己的选择器。

对于那些在网上寻找解决方案的人,我找到了在另一个 SO 线程上编写自定义选择器的替代方法。

app-routing.module.ts

@NgModule({
    imports: [RouterModule.forRoot(routes, {
        paramsInheritanceStrategy: 'always' <---- the important part
    })],
    exports: [RouterModule]
})

解决问题的原始答案: