Angular 守卫中的异步代码无法打开页面

asynchronous code in an Angular guard doesn't open page

设置很简单。我有一个守卫路线的守卫。如果用户的属性locationSaved === true那么我们要让用户进入页面。

如果浏览器令牌的第一次检查为假,我们想发出 HTTP 请求以查看用户对象的 locationSaved 属性 的最新版本是否可能更新为真。

我做了服务器请求,它返回了 true,所以我希望它能打开页面,但不幸的是它没有。我假设它与我在页面中执行的异步请求有关,因为当我用简单的 return true; 替换服务器请求代码时;然后它确实打开了页面。

如果服务器 returns 为真,有人知道我如何使用这个异步请求并导航到该页面吗?

这是我的守卫密码。我设置它会发出异步请求并且服务器返回 true。但是,它不会导航到该页面。

import { Injectable } from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate} from '@angular/router';
import {AuthenticationService} from './auth.service';
import {Observable} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LocationGuardService implements CanActivate {

  constructor(private authService: AuthenticationService) { }

  canActivate(route: ActivatedRouteSnapshot): boolean {
    console.log('entered the guard');
    if (this.authService.isLoggedIn()) {
      if (this.authService.currentUser().user.locationSaved) {
        return true;
      } else {
        this.authService.isLocationSaved()
          .subscribe((status: {saved: boolean}) => {
            console.log('saved', status);
            return status.saved;
          });
      }
    } else {
      return false;
    }
  }
}

不会,因为在 else 块中,您没有 returning 任何东西。而不是 subscribeing,你应该 mapped 到 status.saved

当然,canActivate 方法现在将 return 变成 booleanObservable<boolean>。所以您可能想要更改 canActivate 的 return 类型。

这应该有效:

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate } from '@angular/router';
import { AuthenticationService } from './auth.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class LocationGuardService implements CanActivate {

  constructor(private authService: AuthenticationService) { }

  canActivate(route: ActivatedRouteSnapshot): boolean | Observable<boolean> {
    if (this.authService.isLoggedIn()) {
      if (this.authService.currentUser().user.locationSaved) {
        return true;
      } else {
        return this.authService.isLocationSaved()
          .pipe(map(status => status.saved));
      }
    } else {
      return false;
    }
  }
}