Ограничить маршруты, используя пользовательский соединитель

У меня есть следующая конфигурация маршрута:

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

Чтобы ограничить параметры как числа, я начал искать и после многого времени потратить toooooooooo, я нашел способ в этой закрытой (я не знаю почему) проблеме: 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

Вам нужно будет продолжать раскладывать дочерние компоненты в вашем маршрутизаторе, чтобы эта функция работала из коробки. Следующее работает для меня с маршрутизатором версии 4, и это позволит только параметрам идентификатора быть одним или несколькими номерами, а параметр действия соответствует точному слову "редактировать":

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: '' }
        ]
    }
];

Если использование дочернего компонента не работает для вас, вам придется переписать некоторую логику регулярного выражения в соответствии с вашими потребностями.