私がやろうとしていること:
Plnkrの例-> ここにリンクの説明を入力
この例では、「AddItem」メソッドが表示されます
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」がコンストラクタに挿入されます。
お気づきのように、switchステートメント内のすべての順列をハードコーディングすることは理想的とは言えません。
componentFactoryResolverをコンソールに記録すると、さまざまなファクトリーのMapが含まれていることがわかりました。
CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}
ただし、この地図は非公開であり、簡単にアクセスできません(私が知る限り)。
このファクトリーリストにアクセスするために、どういうわけか私のクラスをローリングするより良い解決策がありますか?
動的コンポーネントを作成しようとしている人々に関する多くのメッセージを見てきました。ただし、これらは多くの場合、実行時にコンポーネントを作成するためのものです。ここで問題になっているコンポーネントはすでに定義済みです。文字列をキーとして使用してファクトリーにアクセスしようとして立ち往生しています。
提案やアドバイスは大歓迎です。
誠にありがとうございます。
利用可能なコンポーネントのマップを定義するか、
const compMap = {
text: PictureBoxWidget,
image: TextBoxWidget
};
または、マップの生成に使用される静的クラスプロパティとして識別子を定義します。
const compMap = [PictureBoxWidget, TextBoxWidget]
.map(widget => [widget.id, widget])
.reduce((widgets, [id, widget]) => Object.assign(widgets, { [id]: widget }), {});
その後、マップは次のように使用されます
let compFactory: ComponentFactory;
if (componentName in compMap) {
compFactory = this.compFactoryResolver.resolveComponentFactory(compMap[componentName]);
} else {
throw new Error(`Unknown ${componentName} component`);
}
Angular 2 DI(Angularから変更されたもの)では文字列に解決されないため、コンポーネントクラスを魔法のように文字列として識別する方法はありません。 1、すべてのDIユニットは文字列として注釈が付けられました)。