Angular 2+:canLoad 用法 [英] Angular 2+ : canLoad usage

查看:50
本文介绍了Angular 2+:canLoad 用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对路由使用 canLoad 函数,但它似乎不起作用.

I'm trying to use the canLoad function with routes, but it doesn't seem to work.

我不知道为什么,也许你不能将它与 canActivate 或其他东西一起使用,但既然我不知道,我想有人会在这里.

I don't know why, maybe you can't use it with canActivate or something, but since I don't know, I thought someone would here.

代码运行,当使用 aot 编译时,我得到这个:

The code runs, when serving with aot compilation I get this :

chunk {admin.module} admin.module.chunk.js, admin.module.chunk.js.map () 28 kB {main} {pilotage.module} {suiviprod.module}
chunk {inline} inline.bundle.js, inline.bundle.js.map (inline) 5.83 kB [entry]
chunk {main} main.bundle.js, main.bundle.js.map (main) 3.5 MB {vendor} [initial]
chunk {pilotage.module} pilotage.module.chunk.js, pilotage.module.chunk.js.map () 17.2 kB {admin.module} {main} {suiviprod.module}
chunk {styles} styles.bundle.js, styles.bundle.js.map (styles) 267 kB {inline} [initial]
chunk {suiviprod.module} suiviprod.module.chunk.js, suiviprod.module.chunk.js.map () 20.4 kB {admin.module} {main} {pilotage.module}
chunk {vendor} vendor.bundle.js, vendor.bundle.js.map (vendor) 5.52 MB [initial]

但是当我进入模块时,控制台日志没有完成.

But when I go to the modules, the console log isn't done.

这是我的路线代码:

logged.module(主路由,看做 app.module)

logged.module (main routing, see it as app.module)

export const loggedRoutes: Routes = [
  {
    path: 'logged', component: LoggedComponent, canActivate: [AuthGuardService], canActivateChild: [AuthGuardService], children: [
      { path: 'profile', component: ProfileComponent, children: [] },
      ...adminRoutes,
      ...mainRoutes,
      ...pilotageRoutes,
      ...suiviProdRoutes,
      { path: 'admin', loadChildren: 'app/logged/admin/admin.module#AdminModule', canLoad: [AdminGuardService] },
      { path: 'pilotage', loadChildren: 'app/logged/pilotage/pilotage.module#PilotageModule', canLoad: [AdminGuardService] },
      { path: 'suiviprod', loadChildren: 'app/logged/suiviprod/suiviprod.module#SuiviprodModule', canLoad: [AdminGuardService] },
      { path: '', redirectTo: '/logged/main/error', pathMatch: 'prefix' }
    ]
  },
];

admin.module(suiviprod 和pilotage 是一样的,只是路由和组件不同)

admin.module (suiviprod and pilotage are the same, just with different routes & components)

export const adminRoutes: Routes = [
  {
    path: 'admin', component: AdminComponent, canActivate: [AdminGuardService], canActivateChild: [AdminGuardService], children: [
      { path: 'validation', component: ValidationComponent, children: [] },
      { path: 'dashboard', component: DashboardComponent, children: [] },
      { path: 'user/:id', component: UserComponent, children: [] },
      { path: 'users', component: UsersComponent, children: [] },
      { path: 'params', component: ParamsComponent, children: [] },
      { path: 'journals', component: JournalsComponent, children: [] },
      { path: 'purge', component: PurgeComponent, children: [] },
      { path: 'groups', component: GroupsComponent, children: [] },
      { path: 'configs', component: ConfigurationComponent, children: [] },
      { path: 'applications', component: ApplicationsComponent, children: [] },
      { path: '', redirectTo: '/logged/admin/dashboard', pathMatch: 'prefix' }
    ]
  },
];

authguard.service(如果本地存储有令牌,canActivate 返回真)

authguard.service (canActivate returns true if the local storage has a token)

@Injectable()
export class AdminGuardService implements CanActivate, CanActivateChild, CanLoad {
  jwtHelper: JwtHelper = new JwtHelper();
  constructor(private router: Router, private alerter: AlertService) { }
  // tslint:disable-next-line:max-line-length
  canActivate(route?: ActivatedRouteSnapshot, state?: RouterStateSnapshot): boolean { return canActivate(route, state, this, [global.roles.admin]); }
  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { return this.canActivate(route, state); }
  canLoad(route: Route): boolean { console.log('coucou'); return canActivate(null, null, this, [global.roles.admin]); }
}

EDIT 守卫使用的 canActivate 函数(适用于 canActivatecanActivateChild):

EDIT The canActivate function, used by the guard (that works well for canActivate and canActivateChild) :

export function canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot, caller: any, userRoles: string[]): boolean {
  try {
    // Get the token
    let token = localStorage.getItem('jwt');

    // If no token found, not connected
    if (!token) {
      caller.alerter.error(`Vous n'êtes pas connecté`);
      caller.router.navigate(['/login']);
      return false;
    }

    // Try to get roles. If it fails, not a valid token.
    let decodedToken = caller.jwtHelper.decodeToken(token);
    let roles: Array<String> = decodedToken.roles.split(',');

    // return true if any role is found
    let found = false;
    for (let role of userRoles) {
      if (roles.indexOf(role) >= 0) { found = true; }
    }
    if (found) { return true; }

    // Role not found => Unauthorized
    caller.alerter.error(`Autorisation manquante`);
    caller.router.navigate(['/logged/main']);
    return false;

  } catch (ex) {
    // Catch the JWT errors
    caller.alerter.error(`La session utilisateur est corrompue`);
    caller.router.navigate(['/login']);
    return false;
  }
}

推荐答案

您不想在主 loggedRoutes const 中定义延迟加载模块的子路由.您应该只定义模块的入口点,然后让模块处理其内部路由.通过在 loggedRoutes 中定义模块的子路由,您实际上已经声明它们是根的一部分应用模块.

You don't want to define your lazy loaded modules' sub routes in your main loggedRoutes const. You should only define an entry point to the module, and then let the module handle its interior routing. By defining your modules' sub routes in loggedRoutes you've actually declared that they're part of your root app module.

canLoad 仅用于延迟加载模块 - 这些模块必须控制自己的路由.根模块无法控制这一点,因为它会知道延迟加载模块的组件,并且不会延迟加载.

canLoad is only for use with a lazy loaded module - and those modules must control their own routing. The root module cannot control this because then it would know about the lazy loaded module's components, and it wouldn't be lazy loaded.

从您的 loggedRoutes 中删除它:

...adminRoutes,
...pilotageRoutes,
...suiviProdRoutes,

...mainRoutes 很好,因为它不是延迟加载模块的一部分.

...mainRoutes is fine as it isn't part of a lazy loaded module.

并确保您的延迟加载模块已注册其路由:

and ensure your lazy loaded modules have their routes registered:

@NgModule({
  imports: [ RouterModule.forChild(adminRoutes) ]
})
export class AdminModule { }

延迟加载的模块希望在内部处理自己的路由,因为您在顶级注册所有路由,您的应用并不关心延迟加载的模块,它会看到您的管理路由并导航到那里,因为它只是正常路线.但是,AOT 编译器会看到您的 loadChildren ,并且它会为您分块您的代码,但是包含您的应用程序的主块还将包含所有应该延迟加载的额外模块.

The lazy loaded modules want to handle their own routing internally, as you're registering all routes at the top level your app does not care about the lazy loaded modules, it will see your admin routes and navigate you there because it's just a normal route. The AOT compiler will see your loadChildrens, however, and it will chunk up your code for you, but your main chunk containing your app will ALSO contain all the extra modules that are supposed to be lazy loaded.

您还应该从 adminRoutes 中删除第一条路由的名称:

You should also drop the name of the first route from your adminRoutes:

path: 'admin', component: AdminComponent...

应该变成

path: '', component: AdminComponent...

路由段 admin 已经由您的模块提供,在主 loggedRoutes 中注册为 admin.

The route segment admin is already provided by your module being registered as admin in the main loggedRoutes.

这篇关于Angular 2+:canLoad 用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆