[英]redirectTo not working when using canActivate guard
The redirectTo
property isn't working in my Angular 2 app. redirectTo
属性在我的 Angular 2 应用程序中不起作用。 I have the following routes in my app.routing.ts
:我的app.routing.ts
有以下路线:
const routes: Routes = [
{ path: '', redirectTo: '/page/1', pathMatch: 'full' },
{ path: 'page', loadChildren: 'app/modules/page/page.module#PageModule' }
]
export const routing = RouterModule.forRoot(routes);
Then, in my page.routing.ts
, I have the following:然后,在我的page.routing.ts
,我有以下内容:
const pageRoutes: Routes = [
{ path: ':id', component: PageComponent, canActivate: [LoginGuard] }
];
export const pageRouting = RouterModule.forChild(pageRoutes);
Every time I access the home page it displays the LoginComponent
for a second, then it disappears.每次我访问主页时,它都会显示LoginComponent
一秒钟,然后消失。 However, it should redirect to the PageComponent
.但是,它应该重定向到PageComponent
。
Why isn't that happening?为什么没有发生这种情况? Why the LoginComponent
is being loaded (even if it's only for a brief second) if the user is already logged in?如果用户已经登录,为什么要加载LoginComponent
(即使它只是短暂的一秒钟)?
Here's my LoginGuard
:这是我的LoginGuard
:
@Injectable()
export class LoginGuard implements CanActivate {
constructor(private af: AngularFire, private router: Router) {}
canActivate(): Observable<boolean> {
return this.af.auth.map(auth => {
if (auth === null) {
this.router.navigate(['/login']);
return false;
} else {
return true;
}
}).first();
}
}
EDIT: Temporarily, I changed the LoginComponent
to redirect to the PageComponent
if a user is logged in. I still wonder, though, why redirectTo
isn't working.编辑:暂时,如果用户登录,我将LoginComponent
更改为重定向到PageComponent
。不过,我仍然想知道为什么redirectTo
不起作用。
I don't know exactly why this is happening, but I believe if you check the LoginGuard before the PageModule loads, it will work. 我不知道为什么会这样,但是我相信如果在PageModule加载之前检查LoginGuard,它将起作用。
app.routing.ts 应用程序路由
const routes: Routes = [
{ path: '', redirectTo: '/page/1', pathMatch: 'full' },
{
path: 'page',
// Call the guard before the module is loaded
canLoad: [ LoginGuard ]
loadChildren: 'app/modules/page/page.module#PageModule'
}
]
export const routing = RouterModule.forRoot(routes);
LoginGuard LoginGuard
@Injectable()
export class LoginGuard implements CanActivate, CanLoad {
constructor(private af: AngularFire, private router: Router) {}
// Add this method to validade the canLoad
canLoad(route: Route): Observable<boolean> {
return this.canActivate();
}
canActivate(): Observable<boolean> {
return this.af.auth.map(auth => {
if (auth === null) {
this.router.navigate(['/login']);
return false;
} else {
return true;
}
}).first();
}
}
This is happening because you call this.router.navigate(['/login']);
这是因为你调用this.router.navigate(['/login']);
directly from your route guard which initializes a new route navigation on top of the one currently running.直接来自您的路线守卫,它会在当前运行的路线上初始化一个新的路线导航。 You create a "race" between two navigations;您在两个导航之间创建了“竞赛”; my guess is the one to /login'
wins because the other one has to lazy load the module (takes some time).我的猜测是/login'
获胜,因为另一个必须延迟加载模块(需要一些时间)。 But after the loading is done, it changes to that route afterwards, hence the "flashing" login popup.但是加载完成后,它会更改为该路由,因此“闪烁”登录弹出窗口。
You should NOT navigate inside a Guard, instead you should always return either a boolean
(to allow navigate true/false) or a UrlTree
if you want to redirect/change the route.您不应该在 Guard 内导航,相反,如果您想重定向/更改路线,您应该始终返回boolean
(以允许导航真/假)或UrlTree
。 The Guard returns the value and the router will then change navigation to the provided UrlTree
for you inside the ongoing/triggered navigation and you won't get any race. Guard 返回该值,然后路由器将在正在进行的/触发的导航中将导航UrlTree
为为您提供的UrlTree
,您将不会遇到任何竞争。
So change your method like this, and it will work correct.所以像这样改变你的方法,它会正常工作。
canActivate(): Observable<boolean|UrlTree> {
return this.af.auth.map(auth => {
if (auth === null) {
return this.router.parseUrl('/login');
}
return true;
}).first();
}
You should see it like this, if you would call this.router.navigate
in several route guards then the router wouldn't know where to navigate to, by returnin a UrlTree this problem is resolved.你应该看到它是这样的,如果你在几个路由守卫中调用this.router.navigate
那么路由器将不知道导航到哪里,通过返回一个 UrlTree 这个问题就解决了。 See also a related question/answer here另请参阅此处的相关问题/答案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.