Как использовать ResolveComponentFactory () но со строкой в качестве ключа

что я пытаюсь сделать:

  • Используйте что-то похожее на "resolveComponentFactory()", но с идентификатором "string", чтобы получить фабрики компонентов.
  • после получения, начните использовать метод" 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 в консоль я заметил, что он содержит карту с различными фабриками.

CodegenComponentFactoryResolver {_parent: AppModuleInjector, _factories: Map}

однако, эта карта является частной и не может быть легко доступны (насколько я могу судить).

есть ли лучшее решение как-то прокатить свой собственный класс, чтобы получить доступ к этому заводскому списку?

Я видел много сообщений о людях, пытающихся создавать динамические компоненты. Однако часто речь идет о создании компонентов во время выполнения. компоненты, о которых идет речь, уже определены, я застрял, пытаясь получить доступ к фабрикам, используя строку в качестве ключа.

любые предложения или советы будут высоко ценится.

спасибо.

1 ответов


это либо определение карты доступных компонентов,

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 были аннотированы как строки).