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

你。 提交于 2019-11-26 17:48:03

问题


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.

Plnkr Example -> enter link description here

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

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.

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

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

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.


回答1:


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).



来源:https://stackoverflow.com/questions/40062970/how-to-use-resolvecomponentfactory-but-with-a-string-as-a-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!