我有一个应用程序,需要将经过身份验证的用户组件和来宾用户组件分开。但我需要,两个组件都将通过'/'路由加载。我写了
{
path: 'desktop',
loadChildren: 'app/member/member.module#MemberModule',
canActivate: [LoggedInGuard],
},
{
path: '',
loadChildren: 'app/guest/guest.module#GuestModule',
canActivate: [GuestGuard],
},
它有效。但是如何制作,两个组件加载相同的URL?
我曾尝试为会员的模块路由编写path: ''
,但未执行第二个路由器规则。
以下是警卫代码:
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;
}
}
这是一个掠夺者:http://embed.plnkr.co/VaiibEVGE79QU8toWSg6/
我该怎么做呢?谢谢
答案 0 :(得分:6)
所以我终于能够做到这一点。 事情是Angular使用第一个匹配策略,所以我们需要以保护类型的方式匹配路由,以确保匹配正确模块的正确路由。
首先我们需要为我们的路线添加自定义matchers,这些路线只会在我们想要的条件(例如用户类型)上匹配它们。
{
path: 'samePath',
matcher: firstMatcher,
loadChildren: '../first/first.module#FirstModule'
},
{
path: 'samePath',
matcher: secondMatcher,
loadChildren: '../second/second.module#SecondModule'
}
匹配代码是这样的: 在这里,我从AppModule注入了AuthService服务,并检查了用户输入的类型。因此可以根据用户类型匹配路由。
import { applicationInjector } from '../../main';
export function firstMatcher (url: UrlSegment[]) {
const auth = applicationInjector.get(AuthService);
return auth.isUserType('admin') ? ({consumed: [url[0]]}) : null;
}
现在我们只需要在主模块中创建applicationInjector
,这样我们就可以在matcher函数中注入服务;
export let applicationInjector: Injector;
platformBrowserDynamic().bootstrapModule(AppModule).then((componentRef) => {
applicationInjector = componentRef.injector;
})
答案 1 :(得分:2)
您可以通过使用Angular的useFactory提供程序提供RouterModule的ROUTES来使用处理应加载哪个模块的模块。
代码可能是这样的。
// HandlerModule
@NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule
],
providers: [
{
provide: ROUTES,
useFactory: configHandlerRoutes,
deps: [SessionService],
multi: true
}
]
})
export class HandlerModule {}
export function configHandlerRoutes(sessionService: SessionService) {
let routes: Routes = [];
if (sessionService.isLoggedIn()) {
routes = [
{
path: '', loadChildren: () => import('app/member/member.module').then(mod => mod.MemberModule)
}
];
} else {
routes = [
{
path: '', loadChildren: () => import(app/guest/guest.module).then(mod => mod.GuestModule)
}
];
}
return routes;
}
然后在您的AppRoutingModule中,路径“”的模块将成为HandlerModule:
// AppRoutingModule
{
path: '',
loadChildren: () => import('app/handler/handler.module').then(mod => mod.HandlerModule)
}
在SessionService之后,您必须在提供方法isLoggedIn的值更改时更新Router.config,因为该应用程序将仅加载首次加载的页面(模块)。这是因为HandlerModule中useFactory提供程序使用的函数“ configHandlerRoutes”仅在我们第一次导航到“”路径时才执行,之后Angular Router已经知道他必须加载哪个模块。
最后,您必须在SessionService中完成
: export class SessionService {
private loggedIn: boolean;
constructor(private router: Router) {
this.loggedIn = false;
}
public isLoggedIn(): boolean {
return this.loggedIn;
}
public setLoggedIn(value: boolean): void {
const previous = this.loggedIn;
this.loggedIn = value;
if (previous === this.loggedIn) {
return;
}
const i = this.router.config.findIndex(x => x.path === '');
this.router.config.splice(i, 1);
this.router.config.push(
{path: '', loadChildren: () => import('app/handler/handler.module').then(mod => mod.HandlerModule)}
);
}
}
就是这样。
如果您想要其他参考,这里是一篇文章,他们使用相同的方法: https://medium.com/@german.quinteros/angular-use-the-same-route-path-for-different-modules-or-components-11db75cac455
答案 2 :(得分:-1)
执行此操作的一种方法是根据用户是否登录来路由到适当的区域。
(即你是否打开空白路线或客串路线,它会被适当地重定向,后退按钮将不起作用)
<强>路线:强>
{
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 (如果已登录则自动路由到MemberComponent):
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;
}
}
答案 3 :(得分:-2)
下面的代码对我有用!!!
路线 = [ { 小路: '', 组件:localStorage.getItem('isVisited')?MainComponent:(()=>{ localStorage.setItem('isVisited','true');return AboutComponent})() } ]