问题
I know how to init components using ComponentFactoryResolver.resolveComponentFactory(AComponentType)
but the method expects a Type
, while in my code I have the name of the type as a string
.
In the Angular API is there a method to resolve by string
?
If not, how can I convert a string to a Type
in TypeScript?
In case that none of the above is possible I will resort to a map but it's not so straightforward as the components I need to instantiate will come from remotely fetched UMD angular component library.
回答1:
You can do the following:
const classesMap = {
AComponentType: AComponentType,
BComponentType: BComponentType
}
And then:
CreateDynamicComponent(typeName: string) {
...
const componentFactory = ComponentFactoryResolver.resolveComponentFactory(classesMap[typeName].prototype.constructor)
...
}
回答2:
I had the same problem, where i need to use a string to select what component to build. After some digging I created a list of the components that is added to the NgModule
export and entryComponents lists.
template-components.ts
export const TEMPLATE_COMPONENTS: Type<any>[] = [ Temp1Component, Temp2Component ]
in my NgModule
class I just add TEMPLATE_COMPONENTS to both exports
and entryComponents
In the component with the ComponentFactoryResolver
you generate a list of Types, with the same string as a key.
let templateTypes: { [name: string]: Type<{}> } =
TEMPLATE_COMPONENTS.reduce((p, c) => { p[c.name] = c; return p }, {})
// templateTypes = {'Temp1Component':Temp1Component,...}
this.componentFactoryResolver.resolveComponentFactory(templateTypes[string]);
This means that you only have to add the components to one place, simplifying adding more components.
Its probably possible to skip the whole TEMPLATE_COMPONENTS
in a separate list step and get the list directly from the NgModule
class, but that will be sometime in the future.
来源:https://stackoverflow.com/questions/49168240/angular-5-instantiate-a-component-from-its-name-as-a-string