CanActivate Guard似乎没有订阅可观察的内容

时间:2018-12-04 12:33:00

标签: javascript angular rxjs

我有一个Angular应用程序,它需要完成许多步骤。每个步骤只能执行一次,并且必须完成所有先前的步骤。为了达到这个目的,我在每条路线上都增加了路线防护。该应用程序在启动时发出http请求以检查状态。但是,路由防护canActivate方法似乎并未订阅更改。

在下面的示例中,statusService更新了状态,该状态应触发防护中的更新。

statusService

@Injectable({
  providedIn: 'root'
})
export class StatusService {

  private stepOneComplete: BehaviorSubject<boolean> = new BehaviorSubject(false);
  private stepTwoComplete: BehaviorSubject<boolean> = new BehaviorSubject(false);

  constructor(
    private http: HttpClient
  ) { }

  public getStepOneComplete(): Observable<boolean> {
    return this.stepOneComplete;
  };

  public updateStepOneComplete(newValue: boolean): void {
    this.stepOneComplete.next(newValue);
  };

  public initialize(): void {
    this.http.get(`${apiUrl}status`)
      .subscribe((data: any) => {
        this.stepOneComplete(data.stepOne);
      });
  };
};

stepOneGuard

@Injectable()
export class StepOneGuard implements CanActivate {

  constructor(
    private service: StatusService,
    private router: Router
  ) {}

  canActivate(): Observable<boolean> {
    return this.service.getStepOneComplete().pipe(
      tap(complete => {
        if(complete){
          this.router.navigate(['/step-two']);
        }
      }),
      map(complete => {
        return !complete;
      })
    );
  }
}

我希望发生的是,在initialize方法运行并更新stepOneComplete之后,路由器应导航至第二步。但是,没有导航发生。如果将console.log放入防护的tap方法中,它将在初始加载时触发,但在调用stepOneComplete.next时不会触发。

2 个答案:

答案 0 :(得分:0)

我认为答案就在这里

public getStepOneComplete(): Observable<boolean> {
  return this.stepOneComplete.asObservable();
}

这就是我在自己的生产代码中所具有的功能,效果很好。

答案 1 :(得分:0)

您不应将后卫视为控制导航的单例。其唯一目的是控制用户是否可以访问页面。

我建议您使用一个状态服务来保存“向导”的状态,然后您只需在每个警卫中对其进行检查。您甚至根本不需要主题。