Angular 2+:canLoad用法 [英] Angular 2+ : canLoad usage
问题描述
我正在尝试将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
函数,由保护程序使用(对canActivate
和canActivateChild
效果很好):
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 loadChildren
s, 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屋!