网站搜索

javascript - 如何通过 ActivatedRouteSnapshot 访问组件?


使用案例

使用 Angular Guard 的 CanActivate 来守护组件。

示例路线

{
 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 的基础知识。有人能指给我一些我可以参考的相关链接/文档吗?

答案#1

route.component 保存了 component 的类型,可以是 string 或 Type<any>,所以如果你想从中获取静态 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

这个问题在这个链接上有一个类似的答案。处理这个问题的另一种方法,可能是使用一个常量来处理paths,其中包含你尝试匹配的内部对象:

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

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

我觉得那样可能更干净。