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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40062970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:55:51  来源:igfitidea点击:

How to use ResolveComponentFactory() but with a string as a key

angulartypescriptdynamicangular2-components

提问by Edward

what I'm trying to do:

我正在尝试做的事情:

  • Use something similar to the "resolveComponentFactory()", but with a 'string' identifier to get Component Factories.
  • Once obtained, start leverage the "createComponent(Factory)" method.
  • 使用类似于“resolveComponentFactory()”的东西,但使用“字符串”标识符来获取组件工厂。
  • 获得后,开始利用“createComponent(Factory)”方法。

Plnkr Example -> enter link description here

Plnkr 示例 ->在此处输入链接描述

In the example, you will see the "AddItem" method

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

}

}

The "compFactoryResolver:ComponentFactoryResolver" is injected in the contructor.

“compFactoryResolver:ComponentFactoryResolver”被注入到构造函数中。

As you will note, having to hard code every permutation in a switch statement is less than ideal.

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

when logging the ComponentFactoryResolver to the console, I've observed that it contains a Map with the various factories.

在将 ComponentFactoryResolver 记录到控制台时,我观察到它包含一个带有各种工厂的 Map。

CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}

However, this map is a private and can't be easily accessed (from what I can tell).

然而,这张地图是私人的,不能轻易访问(据我所知)。

Is there a better solution then somehow rolling my own class to get access to this factory list?

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

I've seen a lot of messages about people trying to create dynamic components. However, these are often about creating components at run time. the components in question here are already pre-defined, I am stuck trying to access factories using a string as a key.

我已经看到很多关于人们试图创建动态组件的消息。然而,这些通常是关于在运行时创建组件。这里有问题的组件已经预先定义,我在尝试使用字符串作为键访问工厂时陷入困境。

Any suggestions or advice are much appreciated.

非常感谢任何建议或意见。

Thank you kindly.

非常感谢你。

回答by Estus Flask

It's either defining a map of available components,

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

const compMap = {
  text: PictureBoxWidget,
  image: TextBoxWidget
};

Or defining identifiers as static class property that will be used to generate a map,

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

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

The map is then used like

然后使用地图

let compFactory: ComponentFactory;

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

There's no way how component classes can be magically identified as strings, because they aren't resolved to strings in Angular 2 DI (something that was changed since Angular 1, where all DI units were annotated as strings).

无法将组件类神奇地识别为字符串,因为它们在 Angular 2 DI 中没有解析为字符串(自 Angular 1 以来发生了变化,所有 DI 单元都被注释为字符串)。