Angular 2+(Angular5)如何在运行时从字符串获取类引用
在Angular 5中通过字符串动态获取类引用(无需提前导入)
我明白你想在Angular 5运行时通过字符串拿到类引用,还不想提前导入的需求——之前尝试window[className]返回undefined其实是Angular的打包机制导致的:TypeScript编译后加上Webpack这类工具的模块封装,你的类默认不会暴露到全局window对象上,所以直接从window里拿不到。下面给你几个可行的方案:
方案1:手动维护全局类注册表
这是最直接的方式,自己创建一个全局的映射表,把需要动态获取的类提前注册进去,之后就能通过字符串键值直接获取:
- 先创建一个注册表文件(比如
class-registry.ts):
// class-registry.ts export const classRegistry: Record<string, any> = {};
- 在每个需要动态获取的类文件里,把类注册到表中:
// my-component.ts import { classRegistry } from './class-registry'; export class MyComponent { // 类的逻辑... } // 注册类,键名就是你之后要用来获取的字符串 classRegistry['MyComponent'] = MyComponent;
- 之后在任意地方,只要导入注册表,就能通过字符串获取类引用:
import { classRegistry } from './class-registry'; const className = 'MyComponent'; const targetClass = classRegistry[className]; console.log(targetClass); // 就能拿到MyComponent的类引用了
如果想保证类型安全,可以给注册表加上泛型约束,避免any带来的类型问题。
方案2:利用Angular的依赖注入容器(针对可注入类/服务)
如果你的目标类是Angular服务(带有@Injectable()装饰器),可以通过Angular的Injector来动态获取,不过需要知道服务的token(通常就是类本身):
import { Injector } from '@angular/core'; import { classRegistry } from './class-registry'; // 假设你已经在注册表中注册了服务的token和类名的映射 constructor(private injector: Injector) {} getDynamicService(className: string) { const serviceClass = classRegistry[className]; if (serviceClass) { return this.injector.get(serviceClass); } return null; }
对于组件类的话,还需要结合ComponentFactoryResolver来创建组件实例,但前提是组件已经被加入到模块的entryComponents数组中(Angular 5里需要手动配置)。
补充说明
Angular本身不会把你的业务类放到全局命名空间里,所有类都是基于ES模块封装的,所以直接从window里找肯定拿不到。上面的方案里,手动维护注册表是最灵活且不需要额外依赖的方式,完全能满足你“避免提前导入”的需求——你只需要在类定义的地方注册一次,之后任何地方都能通过字符串获取。
内容的提问来源于stack exchange,提问作者BBaysinger
相关产品推荐
相关产品推荐

