typescript - Angular 5 - instansiera en komponent från dess namn som en sträng
Jag vet hur man initierar komponenter med ComponentFactoryResolver.resolveComponentFactory(AComponentType)
men metoden förväntar sig en Type, medan jag i min kod har namnet på typen som en string.
Finns det en metod i Angular API för att lösa med string? Om inte, hur kan jag konvertera en sträng till en Type i TypeScript?
Om inget av ovanstående är möjligt kommer jag att använda mig av en karta, men det är inte så enkelt eftersom de komponenter jag behöver instansiera kommer från ett fjärrhämtat UMD Angular-komponentbibliotek.
Svar #1
Du kan göra följande:
const classesMap = {
AComponentType: AComponentType,
BComponentType: BComponentType
}
Och sedan:
CreateDynamicComponent(typeName: string) {
...
const componentFactory = ComponentFactoryResolver.resolveComponentFactory(classesMap[typeName].prototype.constructor)
...
}
Svar #2
Jag hade samma problem, där jag behövde använda en sträng för att välja vilken komponent som skulle byggas. Efter lite grävande skapade jag en lista över komponenterna som läggs till i NgModule export- och entryComponents-listorna.
mall-komponenter.ts
export const TEMPLATE_COMPONENTS: Type<any>[] = [ Temp1Component, Temp2Component ]
i min NgModule-klass lägger jag bara till TEMPLATE_COMPONENTS både till exports och entryComponents
I komponenten med ComponentFactoryResolver genererar du en lista över typer, med samma sträng som nyckel.
let templateTypes: { [name: string]: Type<{}> } =
TEMPLATE_COMPONENTS.reduce((p, c) => { p[c.name] = c; return p }, {})
// templateTypes = {'Temp1Component':Temp1Component,...}
this.componentFactoryResolver.resolveComponentFactory(templateTypes[string]);
Detta innebär att du bara behöver lägga till komponenterna på ett ställe, vilket förenklar att lägga till fler komponenter.
Det är förmodligen möjligt att hoppa över hela TEMPLATE_COMPONENTS i ett separat liststeg och få listan direkt från NgModule-klassen, men det blir någon gång i framtiden.
