angular - Hur man använder ResolveComponentFactory() men med en sträng som nyckel
Det jag försöker göra:
- Använd något liknande "resolveComponentFactory()", men med en 'string'-identifierare för att få komponentfabriker.
- När den har erhållits, börja använda metoden "createComponent(Factory)".
Plnkr Exempel -> ange länkbeskrivning här
I exemplet kommer du att se AddItem-metoden
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);
}
"compFactoryResolver:ComponentFactoryResolver" injiceras i konstruktören.
Som du kommer att märka är det mindre än idealiskt att behöva hårdkoda varje permutation i ett switch-uttryck.
När jag loggar ComponentFactoryResolver till konsolen har jag observerat att det innehåller en Map med de olika fabrikerna.
CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}
Men denna karta är privat och kan inte enkelt nås (såvitt jag kan se).
Finns det en bättre lösning än att på något sätt skapa min egen klass för att få åtkomst till den här fabrikslistan?
Jag har sett många meddelanden om människor som försöker skapa dynamiska komponenter. Men dessa handlar ofta om att skapa komponenter vid körningstid. Komponenterna det gäller här är redan fördefinierade, jag sitter fast och försöker komma åt fabriker med en sträng som nyckel.
Alla förslag eller råd uppskattas mycket.
Tack så mycket.
Svar #1
Det handlar antingen om att definiera en karta över tillgängliga komponenter,
const compMap = {
text: PictureBoxWidget,
image: TextBoxWidget
};
Eller att definiera identifierare som en statisk klass-egenskap som kommer att användas för att generera en karta,
const compMap = [PictureBoxWidget, TextBoxWidget]
.map(widget => [widget.id, widget])
.reduce((widgets, [id, widget]) => Object.assign(widgets, { [id]: widget }), {});
Kartan används sedan som
let compFactory: ComponentFactory;
if (componentName in compMap) {
compFactory = this.compFactoryResolver.resolveComponentFactory(compMap[componentName]);
} else {
throw new Error(`Unknown ${componentName} component`);
}
Det finns inget sätt för hur komponentklasser kan identifieras magiskt som strängar, eftersom de inte löses till strängar i Angular 2 DI (något som ändrades sedan Angular 1, där alla DI-enheter var annoterade som strängar).
