【问题标题】:How to access component via ActivatedRouteSnapshot?如何通过 ActivatedRouteSnapshot 访问组件?
【发布时间】:2021-10-27 14:13:57
【问题描述】:

用例

使用CanActivateAngular Guard 保护组件。

示例路线

{
 path: "my-path",
 component: MyComponent,
 canActivate: [AuthGuard]
}

MyComponent 作为示例组件

export class MyComponent {
  // Dependency required by AuthGuard to allow/deny access
  // Each component declares resources that it guards, along with access levels
  static guardedResources = [
    {"user_profile" : {"access" : "write"}},
    {"posts" : {"access" : "read"}}
  ];
}

AuthGuard 代码

canActivate(route: ActivatedRouteSnapshot) {
  // Component resolution happens at runtime via route.component
  
  // Common logic to read component's guardedResources and match them against
  // user's access privileges lies here
}

当我尝试通过route.component.guardedResources 访问组件属性时,它会抛出

error TS2339: Property 'guardedResources' does not exist on type 'string | Type<any>'.
      Property 'guardedResources' does not exist on type 'string'.

执行console.log(route.component) 会在控制台上显示我的组件主体,因此我相当有信心可以通过适当地类型转换route.component 来解决这个问题以接通guardedResources

可能的解决方案

第 1 步 - 在基类中抽象 guardedResources 并在派生组件中覆盖该属性。

第 2 步 - 将 route.component 类型转换为此基类,以便 guardedResources 可用作有效属性。

我想我在这里缺少一些关于 Angular 或 TypeScript 的基本知识。有人可以指出我可以参考的相关链接/文档吗?

【问题讨论】:

    标签: javascript angular typescript access-control role-based-access-control


    【解决方案1】:

    route.componentcomponent 的类型保存为stringType&lt;any&gt;,因此如果您想从中获取静态guardedResources,您必须在此之前将其转换为MyComponent 类型,如下所示:

    // To make sure that the component type is `MyComponent`
    if (route.component === MyComponent) {
      // Cast the type of route.component` to the type of `MyComponent` to access its static variables:
      const guardedResources = (route.component as typeof MyComponent).guardedResources;
    
      // Do the other stuff here
    }
    

    【讨论】:

      【解决方案2】:

      在这个link 上有一个类似的答案。另一种处理此问题的方法可能是使用您尝试匹配的内部对象处理 paths 的常量:

       export const ROLES = {
         'my-path': {
           {'user_profile' : {'access' : 'write'}},
           {'posts': {'access' : 'read'}}
         }
       }
      

      然后在你的守卫中,你可以简单地检查route 的路径并执行必要的逻辑,而不需要强制转换组件。

      我认为这样可能更干净。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-29
        • 2020-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-01
        相关资源
        最近更新 更多