我想做的:
- 使用类似于"resolveComponentFactory()",但使用'字符串'标识符来获取组件工厂。
- 一旦获得,开始使用"createComponent(Factory)"&;方法。
Plnkr示例->在这里输入链接描述
在本例中,您将看到AddItem
方法
addItem(componentName:string):void{
let compFactory: ComponentFactory;
switch(componentName){
case "image":
compFactory = this.compFactoryResolver.resolveComponentFactory(PictureBoxWidget);
break;
case "text":
compFactory = this.compFactoryResolver.resolveComponentFactory(TextBoxWidget);
break;
}
//How can I resolve a component based on string
//so I don't need to hard cost list of possible options
this.container.createComponent(compFactory);
}
"compFactoryResolver: ComponentFactoryResolver"被注入到构造函数中。
正如您将注意到的,必须硬编码switch语句中的每个排列是不理想的。
当将ComponentFactoryResolver记录到控制台时,我观察到它包含一个包含各种工厂的Map。
CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}
然而,这个map是私有的,不容易访问(据我所知)。
是否有更好的解决方案,然后以某种方式滚动我自己的类来访问这个工厂列表?
我看到很多关于人们尝试创建动态组件的消息。然而,这些通常是关于在运行时创建组件的。这里有问题的组件已经预定义,我被卡住试图访问工厂使用字符串作为键。
任何建议或建议都非常感谢。
它要么定义可用组件的映射,
const compMap = {
text: PictureBoxWidget,
image: TextBoxWidget
};
或者将标识符定义为将用于生成映射的静态类属性,
const compMap = [PictureBoxWidget, TextBoxWidget]
.map(widget => [widget.id, widget])
.reduce((widgets, [id, widget]) => Object.assign(widgets, { [id]: widget }), {});
然后像
那样使用映射let compFactory: ComponentFactory;
if (componentName in compMap) {
compFactory = this.compFactoryResolver.resolveComponentFactory(compMap[componentName]);
} else {
throw new Error(`Unknown ${componentName} component`);
}
组件类不可能被神奇地识别为字符串,因为它们在Angular 2的DI中不会被解析为字符串(从Angular 1开始就改变了,所有的DI单元都被注释为字符串)。