在防护完成之前防止组件装载

时间:2018-03-12 09:23:19

标签: angular rxjs

我想弄清楚是否有办法在守卫完成之前阻止组件加载?

问题

我的组件在保护之前加载,检索有关用户的相关信息,从而无法检查负载。

我目前的设置如下:

AppRouting Module

{
    path: 'sub', component: MasterComponent, canActivateChild: [AuthGuard],
    children: [
      { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
      { path: 'dashboard', component: DashboardComponent }    
    ]
  },

AuthGuard - canActivateChild方法

canActivateChild(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {

    return this.secService.isAuthorized()
      .map((profilePresent: boolean) => {
        if (!profilePresent) {
          this.secService.getProfile().subscribe(
            (data: any) => {
              sessionStorage.setItem('profile', JSON.stringify(data));

              return false;
            }
          );

          return true;
        }

        this.secService.redirectToAuthorization();
        return false;
      });
  }

在我的 Dashboard.component.ts

ngOnInit() {
var name = JSON.parse(sessionStorage.getItem('profile')).name;

console.info(name);
}

这一切都会在控制台上引发错误:

ERROR TypeError: Cannot read property 'name' of null

跟踪它我注意到在组件加载之前警卫没有完成因此错误(它在时间上不存在)。

有关如何管理此

的任何想法

1 个答案:

答案 0 :(得分:0)

因此,如果我理解正确,则在从canActivateChild检索数据后,您需要从this.secService.getProfile()返回的Observable完成。

您只需要重构Observable链,而不是进行嵌套订阅:

return this.secService.isAuthorized()
  .concatMap((profilePresent: boolean) => {
    if (!profilePresent) {
      return this.secService.getProfile()
        .do(data => sessionStorage.setItem('profile', JSON.stringify(data))
        .mapTo(true); // I'm not sure what you really need to do here
    }

    this.secService.redirectToAuthorization()
    return Observable.of(false);
  });

请注意,您无法从subscribe电话中返回值,因此我不知道您想要做什么,但我希望您明白这一点。