4

在每次请求之前,我想确保有可用的用户配置文件。我使用 canActivateChild 守卫来做到这一点。

根据 angular2 的文档,可以返回一个 observable:https ://angular.io/api/router/CanActivateChild

应用程序.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>with routeLink)时,console.log('profile loaded')作品。但是,如果我用 f5 或通过浏览器重新加载页面,它永远不会到达那里..

console.log('load')总是被执行。

编辑

如果我作为canActivateChild回报:

return Observable.of(true).map(() => {
  console.log('Test');
  return true;
});

它工作正常......我明白了console.log('test')

4

2 回答 2

1

我认为它在您得到响应之前已解决,请尝试添加一个重播主题,一旦您的请求返回,该主题将解析为 true 或 false

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()
}
于 2017-09-13T13:42:54.920 回答
0

我在@angular/router. 在我更新它之后,它像预期的那样工作。

于 2017-10-07T13:47:45.827 回答