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

问题描述 投票:8回答:1

我正在做什么:

  • 使用类似于“resolveComponentFactory()”的东西,但使用'string'标识符来获取组件工厂。
  • 获得后,开始利用“createComponent(Factory)”方法。

Plnkr示例 - > enter link description here

在该示例中,您将看到“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);

}

在构造函数中注入“componentFactoryResolver:ComponentFactoryResolver”。

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

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

CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}

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

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

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

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

非常感谢你。

angular typescript dynamic angular2-components
1个回答
7
投票

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

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单元都注释为字符串)。

© www.soinside.com 2019 - 2024. All rights reserved.