使用自定义匹配器限制路由

时间:2017-08-07 02:39:01

标签: angular angular2-routing

我有以下路线配置:

const routes: Routes = [
  {
    component: MyComponent,
    path: '',
    children: [
      {
        component: MyListComponent,
        path: ''
      },
      {
        component: MyFormComponent,
        path: ':id/edit'
      },
      { path: '**', redirectTo: '' }
    ]
  }
];

为了将参数限制为数字,我开始搜索并花费太多时间后,我已经找到了一种关闭(我不知道为什么)问题的方法:https://github.com/angular/angular/issues/12442

因此,我将配置(特别是重要的部分)更改为以下内容:

{
  component: MyFormComponent,
  matcher: ComplexUrlMatcher('id', /[1-9]+\/edit/)
}

export function ComplexUrlMatcher(paramName: string, regex: RegExp) {
    return (
        segments: UrlSegment[],
        segmentGroup: UrlSegmentGroup,
        route: Route) => {

        const parts = [regex];
        const posParams: { [key: string]: UrlSegment } = {};
        const consumed: UrlSegment[] = [];

        let currentIndex = 0;

        for (let i = 0; i < parts.length; ++i) {
            if (currentIndex >= segments.length) {
                return null;
            }
            const current = segments[currentIndex];

            const part = parts[i];
            if (!part.test(current.path)) {
                return null;
            }

            posParams[paramName] = current;
            consumed.push(current);
            currentIndex++;
        }

        if (route.pathMatch === 'full' &&
            (segmentGroup.hasChildren() || currentIndex < segments.length)) {
            return null;
        }

        return { consumed, posParams };
    }
}

来源:https://gist.github.com/matanshukry/22fae5dba9c307baf0f364a9c9f7c115

它几乎正常工作。如果我去这样的路线:

my_path/1

......它有效,但我想要的是:

my_path/1/edit

如何修复此功能才能使其正常工作?

1 个答案:

答案 0 :(得分:2)

您需要继续在路由器中嵌套子组件,以使此功能开箱即用。以下适用于我的路由器版本4,它只允许id参数为一个或多个数字,并且action参数匹配确切的单词“edit”:

const routes: Routes = [
    {
        component: MyComponent,
        path: '',
        children: [
        {
            component: MyListComponent,
            path: ''
        },
        {
            matcher: ComplexUrlMatcher("id", /[0-9]+/),
            component: MyFormComponent,
            {
                matcher: ComplexUrlMatcher("action", /(edit)/),
                component: MyFormEditComponent,
            }
        },
        { path: '**', redirectTo: '' }
        ]
    }
];

如果使用子组件不适合您,则必须重写一些正则表达式逻辑以满足您的需要。