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

查看:95
本文介绍了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和领航相同,只是路线和组件不同)

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返回true)

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]); }
}

编辑 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常量中定义延迟加载的模块的子路由.您应该只定义模块的入口点,然后让模块处理其内部路由.通过在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...

您已经在主loggedRoutes中将其注册为admin的模块已经提供了路由段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天全站免登陆