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.
The @Component decorator identifies the class immediately below it as a component class, and specifies its metadata. In the example code below, you can see that HeroListComponent is just a class, with no special Angular notation or syntax at all.
Firstly, we have to create a custom property to pass the data into a component. This can be done via input binding, which passes data from one component to another, generally from parent to child. This custom input binding is created by using the @Input() decorator.
Create a new Angular application using ng new or open an existing one. Open the command prompt or terminal. Alternatively, if you have your Angular application open in an IDE such as Visual Studio Code, you can use the built-in terminal. The new component will get created in a new folder, inside the src/app directory.
To create a component using the Angular CLI: From a terminal window, navigate to the directory containing your application. Run the ng generate component <component-name> command, where <component-name> is the name of your new component.
You can do the following:
const classesMap = {
AComponentType: AComponentType,
BComponentType: BComponentType
}
And then:
CreateDynamicComponent(typeName: string) {
...
const componentFactory = ComponentFactoryResolver.resolveComponentFactory(classesMap[typeName].prototype.constructor)
...
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With