angular2 guard 不处理页面刷新
angular2 guard not working on page refresh
在每个请求之前,我想确保有可用的用户配置文件。我使用 canActivateChild 守卫来做到这一点。
根据 angular2 的文档,return 一个可观察对象是可能的:https://angular.io/api/router/CanActivateChild
app.routes.ts
export const routes: Routes = [
{
path: '',
canActivateChild: [ProfileGuard],
children: [
{
path: 'home',
component: HomeComponent,
canActivate: [AuthGuard]
},
{
path: 'login',
component: LoginComponent,
canActivate: [GuestGuard]
},
}
];
canActivatedChild
在子路由canActivate
之前执行
profile.guard.ts:
export class ProfileGuard implements CanActivateChild {
constructor(private profileService: ProfileService, private snackbar: MdSnackBar) { }
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {
if (this.profileService.user == null && localStorage.getItem('__token') != null) {
return this.profileService.loadProfile().map((user) => {
console.log('profile loaded');
this.profileService.user = <UserModel>user.data;
return true;
});
}
return true;
}
}
加载配置文件函数:
public loadProfile(): Observable<any> {
console.log('load');
return this.http.get('/profile').map(res => res.json());
}
当我浏览菜单(<a>
和 routeLink
)时,console.log('profile loaded')
有效。但是,如果我使用 f5 或通过浏览器重新加载页面,它永远不会到达那里..
总是执行console.log('load')
。
编辑:
如果我在canActivateChild
return:
return Observable.of(true).map(() => {
console.log('Test');
return true;
});
它工作正常...我得到 console.log('test')
我认为它在您收到回复之前就已经解决了,请尝试添加一个重播主题,一旦您提出请求,该主题就会解析为 true 或 false returns
import {Observable, ReplaySubject} from 'rxjs/Rx';
public loadProfile(): Observable<any> {
console.log('loading profile');
return this.http.get('/profile').map(res => res.json());
}
public isUserLoggedInObs(): Observable<boolean> {
const userLoggedIn: ReplaySubject<boolean> = new ReplaySubject<boolean>;
this.loadProfile.first().subscribe(
user => userLoggedIn.next(user.loggedIn === true)
)
return userLoggedIn.asObservable();
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {
return this.profileService.isUserLoggedInObs()
}
我 运行 在 @angular/router
的 RC 上。在我更新它之后它像预期的那样工作。
在每个请求之前,我想确保有可用的用户配置文件。我使用 canActivateChild 守卫来做到这一点。
根据 angular2 的文档,return 一个可观察对象是可能的:https://angular.io/api/router/CanActivateChild
app.routes.ts
export const routes: Routes = [
{
path: '',
canActivateChild: [ProfileGuard],
children: [
{
path: 'home',
component: HomeComponent,
canActivate: [AuthGuard]
},
{
path: 'login',
component: LoginComponent,
canActivate: [GuestGuard]
},
}
];
canActivatedChild
在子路由canActivate
之前执行
profile.guard.ts:
export class ProfileGuard implements CanActivateChild {
constructor(private profileService: ProfileService, private snackbar: MdSnackBar) { }
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {
if (this.profileService.user == null && localStorage.getItem('__token') != null) {
return this.profileService.loadProfile().map((user) => {
console.log('profile loaded');
this.profileService.user = <UserModel>user.data;
return true;
});
}
return true;
}
}
加载配置文件函数:
public loadProfile(): Observable<any> {
console.log('load');
return this.http.get('/profile').map(res => res.json());
}
当我浏览菜单(<a>
和 routeLink
)时,console.log('profile loaded')
有效。但是,如果我使用 f5 或通过浏览器重新加载页面,它永远不会到达那里..
总是执行console.log('load')
。
编辑:
如果我在canActivateChild
return:
return Observable.of(true).map(() => {
console.log('Test');
return true;
});
它工作正常...我得到 console.log('test')
我认为它在您收到回复之前就已经解决了,请尝试添加一个重播主题,一旦您提出请求,该主题就会解析为 true 或 false returns
import {Observable, ReplaySubject} from 'rxjs/Rx';
public loadProfile(): Observable<any> {
console.log('loading profile');
return this.http.get('/profile').map(res => res.json());
}
public isUserLoggedInObs(): Observable<boolean> {
const userLoggedIn: ReplaySubject<boolean> = new ReplaySubject<boolean>;
this.loadProfile.first().subscribe(
user => userLoggedIn.next(user.loggedIn === true)
)
return userLoggedIn.asObservable();
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {
return this.profileService.isUserLoggedInObs()
}
我 运行 在 @angular/router
的 RC 上。在我更新它之后它像预期的那样工作。