现在在我的 Angular 2 应用程序中,我正在成功处理登录和注销。我还在使用ActivatedRoute
并queryParams
在用户注销然后重新登录时重新加载所有最后加载的组件,所有这些都在同一个会话中。登录组件如下所示:
ngOnInit()
{
// reset login status
this.authenticationService.logout();
// get return url from route parameters or default to '/'
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
}
login(response)
{
this.loading = true;
this.authenticationService.login(this.model.username, this.model.password)
.subscribe(
data =>
{
this.router.navigate(['returnUrl']);
this.reset();
},
error =>
{
this.alertService.error(error, response);
this.loading = false;
});
this.authenticationService.username = this.model.username;
}
我想处理的唯一调整是,如果加载了三个选项卡/组件,当用户注销然后重新登录时,我想将最后一个活动选项卡加载为新的活动选项卡。
现在,我们在我们的应用程序路由文件中使用 AuthGuard 和重定向来在登录成功后的所有情况下重定向到仪表板组件。因此,这可以处理用户输入未知路由以及用户首次登录或在同一会话中再次登录的两种情况。应用程序路由文件如下所示:
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard], data: {contentId: 'dashboard'} },
{ path: 'about', component: AboutComponent, canActivate: [AuthGuard], data: {contentId: 'about'} },
{ path: 'login', component: LoginComponent },
{ path: '**', redirectTo: 'dashboard' }
这是我的 authenticationService 中的相关代码:
login(username: string, password: string)
{
const u = encodeURIComponent(username);
const p = encodeURIComponent(password);
return this.http.post(this.url + this.ver + '/' + 'customers/login/' + u + '/' + p + '?' + this.key, {})
.map((response: Response) =>
{
// login successfully if there's a 200 response
const user = response.json();
// if (user && user.token) {
if (user && (response.status = 200))
{
localStorage.setItem('currentUser', JSON.stringify(user));
console.log('User ' + this.username + ' successfully authenticated with API');
// Track active user id
this._userId = user.data._id;
// Trigger login change
this.change.emit(this);
} else
{
console.log('User ' + this.username + ' not recognized by API');
}
});
}
isAuthenticated()
{
if (localStorage.getItem('currentUser'))
{
return true;
} else
{
return false;
}
}
logout()
{
// remove user from local storage to log user out
localStorage.removeItem('currentUser');
console.log('User successfully logged out');
// Reset active user
this._userId = undefined;
// Trigger event
this.change.emit(this);
}
我的 AuthGuard 文件如下所示:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
{
// Get route content id
let contentId = Object.getPropertyValueAtPath(route, 'data.contentId');
//If route does not have session id, don’t load in tab view
if (!String.isNotNullOrEmpty(contentId))
{
console.error(`Route (${route.routeConfig.path}) does not have a content id.`);
this.router.navigateByUrl(''); // Forward to default page.
return false;
}
if (this.disabled)return true;
if (localStorage.getItem('currentUser'))
{
// logged in so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login', {returnUrl: state.url}]);
return false;
}
但我想做的是加载最后一个活动选项卡/组件,而不是每次都简单地加载仪表板组件。我将如何处理这种期望的行为?Angular 中的路由是否允许我在这里设置一个条件子句,而不是总是默认加载一个默认组件?
我还想到,我可能会这样做的一种方法是在注销之前记下完整的 url 路径,通过window.location.pathname
. 然后我需要将该值传回login()
函数中。仍在尝试弄清楚如何做到这一点,同时还通过以下方式获取所有打开的选项卡/组件:
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';