CanActivate охранники на дочерних маршрутах выполняются до окончания родительского разрешения
Я пытаюсь разрешить данные, прежде чем переходить к дочерним маршрутам, так как я должен использовать эти данные в детской защите. Эта проблема связана с родительским распознавателем, которая разрешает данные после увольнения. Решение занимает много времени для разрешения данных
// app.module.ts
const appRoutes: Routes = [
{ path: 'login', component: LoginComponent },
{
path: '',
component: SiteLayoutComponent,
children: [
{ path: '', redirectTo: 'warehouse', pathMatch: 'full' },
{
path: 'warehouse',
loadChildren: './warehouse/warehouse.module#WarehouseModule'
// loadChildren: () => WarehouseModule
}
],
canActivate: [AuthGuard],
resolve: {
Site: SiteResolver // should be resolved before the guard is invoked.
}
},
{ path: '**', component: PageNotFoundComponent }
];
// warehouse.module.ts
const appRoutes: Routes = [
{ path: '', redirectTo: 'cash', pathMatch: 'full' },
{ path: 'cash', component: CashComponent, canActivate: [RouteGuard] // should be invoked after the parent resolver resloves th data }
];
Здесь родительский распознаватель, то есть SiteResolver, разрешается после того, как вызвана защита от детей, т. Е. RouteGuard. Я хочу, чтобы SiteResolver сначала разрешил данные, а затем должен сработать RouteGuard, как мне этого добиться?
3 ответа
Я не уверен, что это правильный метод. Но, пройдя через множество угловых вопросов, я нашел обходной путь.
Вместо разрешения используйте canActivate для извлечения данных и сохранения данных в службе. Ниже приведен фрагмент кода для того же
@Injectable()
export class FetchUserData implements CanActivate {
constructor(
private userService: UserService,
private httpClient: HttpClient
) {}
public modalRef: BsModalRef;
canActivate() {
return this.httpClient
.get("some/api/route")
.map(e => {
if (e) {
this.userService.setUserDetails(e);
return true;
}
return true;
})
.catch(() => {
return Observable.of(false);
});
}
}
Это сработало для меня хорошо. У вас не будет проблем с обновлением дочернего маршрута.
Замечания по использованию Если указаны и защита, и распознаватели, распознаватели не выполняются до тех пор, пока не будут запущены и успешно завершены все защиты. Например, рассмотрим следующую конфигурацию маршрута:
Порядок выполнения такой: BaseGuard , ChildGuard, BaseDataResolver, ChildDataResolver.
Моим выходом из этой ситуации было обернуть все приложение в ленивый модуль и повесить на него canLoad
{
path: '',
children: [
{
path: '',
canLoad: [PortalResolver],
loadChildren: () => import('./portal/portal.module').then(m => m.PortalModule),
}
],
},