Angular 以角度保存/恢复路由器状态
当用户到达我的应用程序中的一个路由时(该路由受特殊保护),我会将他重定向到一个登录路由,以便执行身份验证 然而,在成功的身份验证之后,我不想将她重定向回她最初到达的路线 如何在Angular中保留中间路由状态,然后重定向到它? 我所说的路由状态是指以下情况:Angular 以角度保存/恢复路由器状态,angular,angular-routing,Angular,Angular Routing,当用户到达我的应用程序中的一个路由时(该路由受特殊保护),我会将他重定向到一个登录路由,以便执行身份验证 然而,在成功的身份验证之后,我不想将她重定向回她最初到达的路线 如何在Angular中保留中间路由状态,然后重定向到它? 我所说的路由状态是指以下情况: 路线本身,即路径 所有查询字符串参数 散列字符串 一种方法是使用服务 以下是一个示例服务: import { Injectable } from '@angular/core'; import { IUser } from './use
- 路线本身,即路径
- 所有查询字符串参数
- 散列字符串
- 一种方法是使用服务
以下是一个示例服务:
import { Injectable } from '@angular/core';
import { IUser } from './user';
import { MessageService } from '../messages/message.service';
@Injectable()
export class AuthService {
currentUser: IUser;
redirectUrl: string;
constructor(private messageService: MessageService) { }
isLoggedIn(): boolean {
return !!this.currentUser;
}
login(userName: string, password: string): void {
if (!userName || !password) {
this.messageService.addMessage('Please enter your userName and password');
return;
}
if (userName === 'admin') {
this.currentUser = {
id: 1,
userName: userName,
isAdmin: true
};
this.messageService.addMessage('Admin login');
return;
}
this.currentUser = {
id: 2,
userName: userName,
isAdmin: false
};
this.messageService.addMessage(`User: ${this.currentUser.userName} logged in`);
}
logout(): void {
this.currentUser = null;
}
}
完整代码如下:
但是如果你找不到它。。。以下是登录组件代码:
import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router } from '@angular/router';
import { AuthService } from './auth.service';
@Component({
templateUrl: './app/user/login.component.html'
})
export class LoginComponent {
errorMessage: string;
pageTitle = 'Log In';
constructor(private authService: AuthService,
private router: Router) { }
login(loginForm: NgForm) {
if (loginForm && loginForm.valid) {
let userName = loginForm.form.value.userName;
let password = loginForm.form.value.password;
this.authService.login(userName, password);
if (this.authService.redirectUrl) {
this.router.navigateByUrl(this.authService.redirectUrl);
} else {
this.router.navigate(['/products']);
}
} else {
this.errorMessage = 'Please enter a user name and password.';
};
}
}
以及要完成的身份验证保护服务:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, Route,
CanActivate, CanActivateChild, CanLoad } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(private authService: AuthService,
private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
console.log('In canActivate: ' + state.url);
return this.checkLoggedIn(state.url);
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
console.log('In canActivateChild: ' + state.url);
return this.checkLoggedIn(state.url);
}
canLoad(route: Route): boolean {
console.log('In canLoad: ' + route.path);
return this.checkLoggedIn(route.path);
}
checkLoggedIn(url: string): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
// Retain the attempted URL for redirection
this.authService.redirectUrl = url;
this.router.navigate(['/login']);
return false;
}
}在玩了一会儿路由器之后,我终于实现了我想要的解决方案。我将在这里与你分享 下面是
IntermediateNavigationService
的实现:
从'rxjs/Subscription'导入{Subscription};
从'@angular/Router'导入{NavigationCancel,NavigationEnd,Router};
从“@angular/core”导入{Injectable};
@可注射()
导出类中介服务{
私有savedUrl:string;
专用路由器订阅:订阅;
构造函数(专用路由器:路由器){
}
startWatch(){
this.routerSubscription=this.router.events
.订阅(事件=>{
if(导航的事件实例取消){
//正在从已取消的路由保存URL。
这个.saveUrl(event.url);
}else if(NavigationEnd的事件实例){
//若用户离开登录页面,则清除保存的URL。
如果(!event.url.match(/^\/登录/){
if(this.hasSavedUrl()){
这个.clearsavedur();
}
}
}
})
;
}
秒表(){
this.routerSubscription.unsubscribe();
}
saveUrl(url:string){
this.savedUrl=url;
}
哈萨维杜尔(){
return!!this.savedUrl;
}
getSavedUrl(){
返回这个.savedUrl;
}
Clearsavedur(){
this.savedUrl=null;
}
goToSavedUrl():承诺{
返回this.router.navigateByUrl(this.savedUrl)。然后(结果=>{
如果(结果){
这个.clearsavedur();
}
返回结果;
});
}
}
这项服务背后的理念非常简单。当被startWatch()
方法激活时(您应该在应用程序生命周期中尽早这样做,例如在AppComponent构造函数中),它开始监视路由器事件,特别是过滤NavigationCancel
和NavigationEnd
事件
- 当发生
时,这意味着我们的身份验证路由保护阻止了对目标路由的导航。因此,我们将跳过的URL保存在服务私有变量中NavigationCancel
- 当发生
时,我们检查用户是否离开了我们的登录路径。在这种情况下,我们对保存保存的URL不再感兴趣,因此我们将清除它。否则,当用户被重定向到他不再感兴趣的URL时,可能会导致奇怪的行为NavigationEnd
if(this.intermediateNavigationService.hasSavedUrl()){
this.intermediateNavigationService.goToSavedUrl();
}否则{
this.navigationService.redirectAfterSignIn();
}
简而言之:我们只是检查是否有保存的URL,然后导航到它,如果没有重定向到默认的URL
如果您对某个时刻的状态不再感兴趣,只需调用stopWatch()
,即可取消路由器事件订阅。这可以在成功登录后进行,实际上是为了保留资源(如果您不打算将此服务用于与身份验证无关的类似行为)
如果用户已经通过身份验证,则无需调用startWatch()
以下是您的AppComponent
的外观:
从'@angular/core'导入{Component as NgComponent};
从“./authentication/authentication state.service”导入{AuthenticationStateService};
从“./services/intermediate-navigation.service”导入{IntermediateNavigationService};
@NgComponent({})
导出类MyAppComponent{
建造师(
私有authenticationStateService:authenticationStateService,
私人中介服务:中介服务
) {
//启用中间URL处理。
如果(!this.authenticationStateService.isAuthenticated()){
this.intermediateNavigationService.startWatch();
}
//正在侦听身份验证事件。
此.authenticationStateService.onAuthenticated().subscribe(()=>{
this.intermediateNavigationService.stopWatch()
});
}
}
我希望它能帮助别人。你好,黛博拉!谢谢你的回答。然而,我更感兴趣的是从路由器获取当前URL的部分,以及在登录后实际重定向回它的部分。你的答案中缺少这两部分。我提供了完整源代码的链接。。。但是如果你找不到它。。。我在上面的答案中添加了登录组件代码。