Использование relativeTo от охранника на нескольких модулях функций

#angular

Вопрос:

У меня есть два лениво загруженных функциональных модуля, которые следуют одному и тому же потоку (1. Выберите, 2. Просмотрите, 3. Подтвердите). Я хочу защитить шаг обзора и вернуться назад, чтобы выбрать с одним защитником для обоих модулей. Это означает, что правило навигации должно понимать контекст модуля, в котором вы находитесь в данный момент, и направлять вас к одному /enroll/select или /change/select другому соответственно. Я думал, что смогу добиться этого с relativeTo помощью свойства, но я получаю следующую ошибку.

Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'select' Error: Cannot match any routes. URL Segment: 'select'

Вот Стекблитц с минимально воспроизведенным примером.

 const appRoutes = [
  { path: 'home', component: HomeComponent },
  {
    path: 'enroll',
    loadChildren: () => import('./enroll.module').then((m) => m.EnrollModule),
  },
  {
    path: 'change',
    loadChildren: () => import('./change.module').then((m) => m.ChangeModule),
  },
  { path: '', redirectTo: '', pathMatch: 'full' },
];
 
 const enrollRoutes = [
  { path: 'select', component: EnrollSelectComponent },
  { path: 'review', component: EnrollReviewComponent, canActivate: [MyGuard] },
  { path: 'confirm', component: EnrollConfirmComponent },
  { path: '', redirectTo: '', pathMatch: 'full' },
];
 
 export class MyGuard implements CanActivate {
  constructor(private router: Router, private route: ActivatedRoute) {}

  canActivate() {
    this.router.navigate(['select'], { relativeTo: this.route });
    return false;
  }
}
 

Ответ №1:

Изменение вашей защиты на следующее должно заставить ее работать:

 export class MyGuard implements CanActivate {
    constructor(private router: Router) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        this.router.navigate([state.root.firstChild.url.toString(), 'select']);
        return false;
     }
}
 

Краткое объяснение:

Введение активированного маршрута сработало не так, как вы ожидали. Маршрут всегда был » маршрутом. Но вы можете работать с атрибутами моментального снимка, которые я добавил в метод canActivate. К сожалению, я не смог заставить его работать с relativeTo, так как он полагается на активированный маршрут (а не на снимок).

Комментарии:

1. Это, безусловно, работает, я хотел бы, чтобы было более красноречивое решение, которое не включало бы столь глубокое погружение в состояние маршрута. Я до сих пор также не до конца понимаю, почему маршрут есть '' , а не 'enroll' нет .

2. Охранник — это своего рода верхушка для активированного маршрута. На самом деле он еще не активирован. Возможно, он будет активирован в зависимости от результата охранника. В документации ActivatedRoute говорится, что он доступен для компонентов.