简体   繁体   English

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

[英]CanActivate Guard doesn't seem to subscribe to observable

I have an angular application which has a number of steps to complete. 我有一个角度应用程序,它需要完成许多步骤。 Each step can only be done once and must have all previous steps complete. 每个步骤只能执行一次,并且必须完成所有先前的步骤。 To achieve this I have added route guards to each route. 为了达到这个目的,我在每条路线上都增加了路线防护。 The application makes a http request on start to check the status. 该应用程序在启动时发出http请求以检查状态。 However the route guard canActivate method doesn't seem to be subscribing to changes. 但是,路由防护的canActivate方法似乎并未订阅更改。

In the below example statusService updates the status which should trigger an update in the guards. 在下面的示例中, statusService更新状态,这将触发防护中的更新。

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 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;
      })
    );
  }
}

What I expect to happen is that after the initialize method runs and updates stepOneComplete then the router should navigate to step two. 我希望发生的是,在initialize方法运行并更新stepOneComplete之后,路由器应导航至第二步。 However no navigation occurs. 但是,没有导航发生。 If I put a console.log in the tap method of the guard it fires on initial load but not when stepOneComplete.next is called. 如果将console.log放置在后卫的tap方法中,则它会在初始加载时触发,但在stepOneComplete.next时不会stepOneComplete.next

I think the answer is here: 我认为答案在这里:

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

This is what I have in my own production code, works just fine. 这就是我在自己的生产代码中可以正常运行的内容。

You should not see a guard as a singleton that controls navigation. 您不应将后卫视为控制导航的单例。 Its only purpose is to control whether the user can access a page or not. 其唯一目的是控制用户是否可以访问页面。

I suggest you to have a state service that holds the state of your "wizard", and then you would simply check it in every guard. 我建议您有一个状态服务来保存“向导”的状态,然后您只需在每个警卫中检查它即可。 You shouldn't even need Subjects at all. 您甚至根本不需要主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM