【发布时间】:2018-02-21 23:46:21
【问题描述】:
我在尝试通过不同路线导航时遇到问题。
我有两个不同的路由模块。
app.routes.ts:
仅包含LoginPage:
export const routes: Routes = [
{
path: 'login',
component: LoginPageComponent,
canActivate: [PreventLoggedInAccess]
},
{
path: '',
redirectTo: 'login',
pathMatch: 'full'
},
{
path: '**',
redirectTo: 'login'
}
];
export const Routing: ModuleWithProviders =
RouterModule.forRoot(routes, { useHash : true });
使用 PreventLoggedInAccess.canActivate,如果用户已经登录,则将他重定向到带有 /app 前缀和子路由 home 的登录部分。定义为:
canActivate(): boolean {
if (!this._authService.isAuthenticated()) {
return true;
}
this._router.navigate(['/app/home']);
return false;
}
pages.routes.ts:
包含所有/app 子路由,只有在用户登录时才能访问。这是使用AuthGuardService.canActivateChild 实现的:
export const pageRoutes: Routes = [
{
path: 'app',
component: PagesComponent,
canActivateChild: [AuthGuardService],
children: [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomePageComponent },
{ path: 'contents', component: ContentsComponent },
]
}
];
export const Routing: ModuleWithProviders = RouterModule.forChild(pageRoutes);
如果用户未登录,后者将重定向到/login。它定义为:
canActivateChild(): boolean {
if (this._authService.isAuthenticated()) {
return true;
}
this._router.navigate(['login']);
return false;
}
当我从
app/home导航到app/contents时,它只会在导航两次后转到ContentsComponent。所以,如果我做两次this._router.navigate(['app/components']);它可以工作,如果我只做一次,路线会从app/home更改为app/route1ms,然后返回到app/home,而如果我再做一次它改变了路线。 同时,如果我在app/contents并尝试导航到app/home,它会更改路线就好了。
isAuthenticated 工作正常。两个 authguard 都可以正常工作,因此,如果我在未登录时尝试访问任何 app 子路由,我将被重定向到登录,如果我在登录时尝试访问 login,我将被重定向到app/home.
我设法调试了一下,我注意到以下流程:
- 第一次尝试 -
app/home->app/contents:-
navigate(['app/contents'])被调用 -
PreventLoggedInAccess.canActivate被调用 -
AuthGuardService.canActivateChild被调用
-
- 第二次尝试 -
app/home->app/contents:-
navigate(['app/contents'])被调用 -
AuthGuardService.canActivateChild被调用
-
当然,预期的行为是第二种。
编辑
从PreventLoggedInAccess.canActivate 中删除this._router.navigate([/app/home]); 可以解决问题
canActivate(): boolean {
if (!this._authService.isAuthenticated()) {
return true;
}
return false;
}
但是,我仍然不明白 为什么在导航到 app 孩子时会调用 PreventLoggedInAccess.canActivate,即使 AuthGuardService.canActivateChild 已附加到它?为什么只在第一次尝试时调用它?
【问题讨论】:
-
尝试使用
enableTracing看看发生了什么:RouterModule.forRoot(routes, { useHash : true, enableTracing: true }); -
还值得检查一下 isAuthenticated() 第一次和第二次所说的内容。
-
你的模块是什么样的?我想知道合并路线的顺序是否导致问题?
标签: angular typescript angular-routing angular-router angular-router-guards