12

我在尝试浏览不同的路线时遇到问题。

我有两个不同的路线模块。

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']);它会起作用,如果我只做一次,路线会在 1ms内从app/hometo变为,而如果我第二次做它会改变路线。同时,如果我在里面并尝试导航到它会改变路线就好了。app/routeapp/homeapp/contentsapp/home

isAuthenticated工作正常。app两个 authguard 都工作得很好,所以,如果我在未登录时尝试访问任何子路由,我会被重定向到 login,如果我login在登录时尝试访问,我会被重定向到app/home.

我设法调试了一下,我注意到以下流程:

  • 第一次尝试app/home--> app/contents
    • navigate(['app/contents'])叫做
    • PreventLoggedInAccess.canActivate叫做
    • AuthGuardService.canActivateChild叫做
  • 第二次尝试app/home--> app/contents
    • navigate(['app/contents'])叫做
    • AuthGuardService.canActivateChild叫做

当然,预期的行为是第二​​种。

编辑

删除解决了this._router.navigate([/app/home]);问题PreventLoggedInAccess.canActivate

canActivate(): boolean {
  if (!this._authService.isAuthenticated()) {
      return true;
  }
  return false;
}

但是,我仍然不明白为什么PreventLoggedInAccess.canActivate在导航到一个app孩子时会调用它,即使它AuthGuardService.canActivateChild是依附的?为什么只在第一次尝试时调用它?

4

1 回答 1

2

您已经提到 pageRoute 可以拥有 app 的所有子子级,因此它的路由文件应该包含该模块。

因此可以正确使用延迟加载和守卫的概念。我通过假设您的 pageRoute 模块是 App 的子模块来回答这个问题。

我建议只使用一次 AuthGuard。AuthGaurd 应该在包含其他模块或组件的模块上使用,而不是在登录组件本身上。

这里的页面模块是延迟加载的,只有当 authguard 返回 true 时才能激活。如果为 false,用户将导航到登录。

应用程序.route.ts

const routes: Routes = [
  {
    path: '',
    loadChildren: './pages/pages.module#PagesModule',
    canActivate: [AuthGuardService]
  },
  { path: 'login', loadChildren: './login/login.module#LoginModule' },

];

AuthGuard

canActivateChild(): boolean {
  if (this._authService.isAuthenticated()) {
      return true;
  }
  this._router.navigate(['/login']);
  return false;
}

页面.route.ts

const routes: Routes = [
  {
    path: '', component: PageComponent,
     children: [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: HomePageComponent },
  { path: 'contents', component: ContentsComponent },


     ]
  }
];

如果您想在当前路由条件下进行调试,您可以使用Chrome 网上商店中的Augury

于 2018-02-18T15:48:54.903 回答