如何使用ResolveComponentFactory()但使用字符串作为键

Edw*_*ard 12 dynamic typescript angular2-components angular

我正在做什么:

  • 使用类似于"resolveComponentFactory()"的东西,但使用'string'标识符来获取组件工厂.
  • 获得后,开始利用"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);
Run Code Online (Sandbox Code Playgroud)

}

"compFactoryResolver:ComponentFactoryResolver"在构造函数中注入.

正如您将注意到的,必须对switch语句中的每个排列进行硬编码都不太理想.

将ComponentFactoryResolver记录到控制台时,我发现它包含一个包含各种工厂的Map.

CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}
Run Code Online (Sandbox Code Playgroud)

但是,这张地图是私人的,无法轻易访问(据我所知).

有没有更好的解决方案然后以某种方式滚动我自己的类来访问这个工厂列表?

我看过很多关于人们试图创建动态组件的消息.但是,这些通常是在运行时创建组件.这里讨论的组件已经预先定义,我试图使用字符串作为键来访问工厂.

任何建议或建议都非常感谢.

非常感谢你.

Est*_*ask 12

它要么定义可用组件的映射,

const compMap = {
  text: PictureBoxWidget,
  image: TextBoxWidget
};
Run Code Online (Sandbox Code Playgroud)

或者将标识符定义为将用于生成地图的静态类属性,

const compMap = [PictureBoxWidget, TextBoxWidget]
.map(widget => [widget.id, widget])
.reduce((widgets, [id, widget]) => Object.assign(widgets, { [id]: widget }), {});
Run Code Online (Sandbox Code Playgroud)

然后使用地图

let compFactory: ComponentFactory;

if (componentName in compMap) {
    compFactory = this.compFactoryResolver.resolveComponentFactory(compMap[componentName]);
} else {
    throw new Error(`Unknown ${componentName} component`);
}
Run Code Online (Sandbox Code Playgroud)

组件类没有办法神奇地识别为字符串,因为它们没有被解析为Angular 2 DI中的字符串(自Angular 1以来已经改变了,其中所有DI单元都注释为字符串).