Angular2 - 返回布尔值,订阅canActivate

Rit*_*Rit 6 subscribe angular

我是Angular中的新手,我需要实现一个返回true/false的函数,我将在canActivate中使用return,但是这个函数使用http.get的api,所以就像通信是异步的一样,这个函数总是返回FALSE ,因为http.get还在进行中.

我的班主任:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

    let url: string = state.url;


    if (this.loginService.isLoggedIn()) {
        return true;
    }

    this.loginService.redirectUrl = url;

    this.router.navigate(['login']);

    return false;
}
Run Code Online (Sandbox Code Playgroud)

和函数isLoggedIn()

isLoggedIn() {

    let logged: boolean = false;

    this.http.get('api/values', this.httpService.headers())
        .map((res: Response) => {
            logged = res.json();
        });

    return logged;

}
Run Code Online (Sandbox Code Playgroud)

我读了很多问题,但我找不到答案.

kit*_*kit 8

后卫说明它可以回归

Observable<boolean>, Promise<boolean> or boolean
Run Code Online (Sandbox Code Playgroud)

所以将isLoggedIn更改为:

isLoggedIn() {

  return this.http.get('api/values', this.httpService.headers())
    .take(1)
    .map((res: Response) => res.json());
}    
Run Code Online (Sandbox Code Playgroud)

更新

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    let url: string = state.url;

    return this.isLoggedIn().map(loggedIn => {
      if(!loggedIn) {
        this.loginService.redirectUrl = url;
        this.router.navigate(['login']);
      }
      return loggedIn;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • AFAIK你仍然需要在末尾添加`.first()`或`.take(1)`,以便在第一个事件之后observable关闭.否则路由器会永远等待. (2认同)
  • Observable是懒惰的,在调用`subsribe()`之前不做任何事情.当从`canActivate`返回observable时,路由器调用`subsribe()` (2认同)