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 和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
函数(适用于 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
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 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...
路由段 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屋!