I have an application, which need to separate authenticated and guest users components. But I need, that both components will be loaded by '/' route. I wrote
{
path: 'desktop',
loadChildren: 'app/member/member.module#MemberModule',
canActivate: [LoggedInGuard],
},
{
path: '',
loadChildren: 'app/guest/guest.module#GuestModule',
canActivate: [GuestGuard],
},
And it works. But how to make, that both component load by same url?
I had tried to write path: '' for Member's module route, but the second router rule is not performed.
Here are guards code:
LoggedInGuard:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if(this.sessionService.isLoggedIn()) {
return true;
} else {
return false;
}
}
GuestGuard:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if(!this.sessionService.isLoggedIn()) {
return true;
} else {
return false;
}
}
Here is a plunker: http://embed.plnkr.co/VaiibEVGE79QU8toWSg6/
How should I do it properly? Thank you
So i was finally able to do this. The thing is Angular uses first match policy, so we need to match routes in a guard-type way, to be sure that right route with right module will be matched.
First thing we need to add custom matchers for our routes which will only match them on conditions that we want (user type for example).
{
path: 'samePath',
matcher: firstMatcher,
loadChildren: '../first/first.module#FirstModule'
},
{
path: 'samePath',
matcher: secondMatcher,
loadChildren: '../second/second.module#SecondModule'
}
And matchers code is something like this: In here i injected AuthService service from AppModule, and checked users type with it. So routes can be matched according to users type.
import { applicationInjector } from '../../main';
export function firstMatcher (url: UrlSegment[]) {
const auth = applicationInjector.get(AuthService);
return auth.isUserType('admin') ? ({consumed: [url[0]]}) : null;
}
And now only thing we need is to create applicationInjector in our main module, so we could inject service in our matcher-function;
export let applicationInjector: Injector;
platformBrowserDynamic().bootstrapModule(AppModule).then((componentRef) => {
applicationInjector = componentRef.injector;
})
One way to do this will be to route to appropriate area depending on whether the user is logged in or not.
(i.e. whether you open blank route or guest route, it will get redirected appropriately, and back button won't work)
Routes:
{
path: '',
loadChildren: 'app/member/member.module#MemberModule',
canActivate: [LoggedInGuard],
},
{
path: 'guest',
loadChildren: 'app/guest/guest.module#GuestModule',
canActivate: [GuestGuard],
}
LoggedInGuard::
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if(this.sessionService.isLoggedIn()) {
return true;
} else {
// route to 'guest' if not logged in
this.router.navigate(['/guest'], { replaceUrl: true });
return false;
}
}
GuestGuard (with automatic route to MemberComponent if logged in):
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if(this.sessionService.isLoggedIn()) {
// route to member area if already logged in
this.router.navigate(['/'], { replaceUrl: true });
return false;
} else {
return true;
}
}
来源:https://stackoverflow.com/questions/41928727/angular-2-different-components-with-same-route