web-dev-qa-db-ja.com

ResolveComponentFactory()を使用する方法(ただし、キーとして文字列を使用)

私がやろうとしていること:

  • 「resolveComponentFactory()」に似たものを使用しますが、コンポーネントファクトリを取得するには「文字列」識別子を使用します。
  • 取得したら、「createComponent(Factory)」メソッドの活用を開始します。

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}

ただし、この地図は非公開であり、簡単にアクセスできません(私が知る限り)。

このファクトリーリストにアクセスするために、どういうわけか私のクラスをローリングするより良い解決策がありますか?

動的コンポーネントを作成しようとしている人々に関する多くのメッセージを見てきました。ただし、これらは多くの場合、実行時にコンポーネントを作成するためのものです。ここで問題になっているコンポーネントはすでに定義済みです。文字列をキーとして使用してファクトリーにアクセスしようとして立ち往生しています。

提案やアドバイスは大歓迎です。

誠にありがとうございます。

13
Edward

利用可能なコンポーネントのマップを定義するか、

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ユニットは文字列として注釈が付けられました)。

11
Estus Flask