如何在Angular 2中实现等待连接的AuthGuard

时间:2016-06-30 10:37:27

标签: typescript angular rxjs

我正在使用带有@ angular / router alpha.8的Angular 2(RC.3)创建Web应用程序。 这个新的路由器提供" Guard",它帮助我们实现处理授权重定向。

正式文档写了如何创建和使用Guard,但其示例代码没有考虑连接时间。 https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard

所以我想在其中使用Observable(或Promise)。

export class ApiService {
  constructor(private _http: Http) {}
  head(url: string): Observable<any> {
    const req: any = { method: RequestMethod.Head, url: URI_SCHEME + url };

    return this._http.request(new Request(req));
  }
}

export class AuthGuard implements CanActivate {
  constructor(private _api: ApiService) {}

  canActivate(): Observable<boolean> {
    return this._api.head('/users/self').subscribe(
      (): Observable<boolean> => {
        // when gets 200 response status...
        return Observable.of(true);
      },
      (): Observable<boolean> => {
        // when gets 401 error response...
        // TODO: redirect to sign-in page.
        return Observable.of(false);
      }
    );
  }
}

但在上面的代码中,canActivate()函数会返回Subscription个实例,因为Observable.prototype.subscribe()会返回Subscription

我该怎么办?

2 个答案:

答案 0 :(得分:6)

只需使用map()代替subscribe()。路由器自己进行订阅以发起请求。

请勿忘记导入map Angular 2 HTTP GET with TypeScript error http.get(...).map is not a function in [null]

我认为这应该做你想要的:

export class AuthGuard implements CanActivate {
  constructor(private _api: ApiService) {}

  canActivate(): Observable<boolean> {
    return this._api.head('/users/self')
    .map(response => {
      this.doSomethingWithResponse(response.json()));
      return true;
    })
    .catch(err => Observable.of(false));
  }
}

答案 1 :(得分:0)

如果多个路由订阅同一个可观察项,它将多次调用后端。需要添加publishReplay:httpClient.get('url')。pipe(publishReplay(1),refCount());