ngrx/router-store - 路由参数选择器返回子路由的未定义



我设置了以下路由:

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");

它确实在"父"级别组件(路由(上工作。这意味着当用户转到edit/some-concert选择器返回一些音乐会时。但是对于/edit/some-concert/edit/songs/1(在子组件中(,它返回undefined。我不知道为什么。

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

我可以尝试哪些新事物?

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

app-routing.module.ts

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

解决该问题的原始答案:https://stackoverflow.com/a/51817329/5775417

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

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善意地在推特上回复说:

路由器存储的选择器向下遍历到树中最低的活动路由,这就是您不会获得该参数的原因。如果需要树中的所有参数,则需要自定义选择器。

所以是的,你必须创建自己的选择器。

最新更新