【问题标题】:Angular 2 route guard isn't waiting for value to be setAngular 2 路由守卫不等待设置值
【发布时间】:2017-01-26 09:34:09
【问题描述】:

我有这个路由守卫,它应该检查用户的角色以及路由定义中定义的roleAccess 属性。

我面临的问题是.map 的执行与accounts.isSelfPending 无关,只有当它为假时(它以@ngrx/store 中的null 开始)才允许.map 运行。

我怎样才能做到这一点?

编辑:我意识到我的问题可能有点含糊,我需要等待来自组件层次结构更高层的/self 请求中的用户信息,并且存储在商店中。

现在的问题是,/self 请求甚至没有被触发,尽管我的DashboardComponent 被触发,而DashboardComponent 又将AdsComponent 作为路由中的子节点之一。 (这是我目前试图用这个守卫锁定的路线)。

为什么它甚至不触发/self 请求?我认为这是这个问题的一部分。

return this.store.select('accounts')
  .let((state: Observable<IAccountsStorage>) => state.filter((accounts: IAccountsStorage) => accounts.isSelfPending !== null && accounts.isSelfPending === false)))
  .map((accounts: IAccountsStorage) => {

    this.route.data.subscribe(
      data => {

        if (accounts.self) {

          if (accounts.self.role !== data['roleAccess'] && (data['roleAccess'] !== 0 || data['roleAccess'] !== undefined || data['roleAccess'] !== null)) {
            return this.router.navigateByUrl('admin/dashboard');
          }
          else {
            return true;
          }
        }
      }
    );
  }
).first();

【问题讨论】:

  • 遵循你的结构有点困难。你认为你可以制作一个 Plunkr 来复制 pb 以便我可以帮助你吗? :)
  • @Maxime 如果我现在有更多时间,我会这样做,但是我设法找到了一个不错的解决方案,现在可以通过转向另一个方向来解决。正如您在我自己的回答中看到的那样。

标签: angular typescript angular2-router angular2-guards


【解决方案1】:

我知道那是一年之后的事了,但我在 Angular 中的 Stores 和 Guards 也遇到了类似的问题。我认为您的问题与 State 最初有一个 NULL 用户对象有关——即使只是在您从现有令牌设置用户时很短暂。

NULL 先通过但需要过滤掉,像这样:

canLoad(route: Route): Observable<boolean> | Promise<bolean> | boolean {
    return this.store.select(fromRoot.getUser)
        .filter(user => user != null) // ** THIS IS THE KEY TO SKIP NULL USER **
        .map(user => {
            //code t check user role
        }).take(1); // or .first() -- doesn't seem to be necessary for canActivate guards
}

注意:上面的代码反映了 Store 代码的当前编写方式——或者,至少,它是按照当前 ngrx/store 4.x code examples 的编写方式设计的,这与您在原始问题。

【讨论】:

    【解决方案2】:

    在意识到使用 store 作为中间人会导致太多问题后,我决定直接调用 api,最终得到一个更清晰的守卫,实际上可以按预期工作。

    我认为这可能对其他人有所帮助,因此我将在此处留下最终解决方案:

    canLoad(): Observable<boolean> {
    
      return this.accountsApi.getSelf()
        .map(res => {
    
          if (res.data.role === 1) {
            return true;
          }
          else {
            return this.router.navigate(['admin/dashboard']);
          }
        })
        .catch(err => {
          return this.router.navigate(['admin/dashboard']);
      });
    }
    

    但是,如果有人知道如何使用原始代码解决问题,请提供,因为我很好奇如何使用商店实际解决问题。

    【讨论】:

      猜你喜欢
      • 2018-01-10
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 2019-11-11
      • 1970-01-01
      • 2019-02-04
      • 2018-12-04
      • 1970-01-01
      相关资源
      最近更新 更多