2016-10-15 2 views
6

то, что я пытаюсь сделать:Как использовать ResolveComponentFactory(), но со строкой в ​​качестве ключа

  • Используйте что-то похожее на «resolveComponentFactory()», но с идентификатором «строка», чтобы получить Компонентные заводы.
  • После получения, начните использовать метод «createComponent (Factory)».

Plnkr Пример ->enter link description here

В примере, вы будете видеть "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

Как вы можете ожидать, что класс будет идентифицироваться строкой, если он не идентифицирован строкой внутри? Имя класса «PictureBoxWidget» является чем-то вроде «a» в мини-приложении, а имя класса «TextBoxWidget», скорее всего, «а». Вы можете сохранить свою собственную карту компонентов, но вам нужно явно их перечислять. Это всегда более надежный подход, чтобы иметь фиксированный список альтернатив, которые могут быть проверены и протестированы. – estus

ответ

6

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

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`); 
} 

Невозможно каким образом определить классы компонентов как строку s, потому что они не разрешены к строкам в Angular 2 DI (то, что было изменено с Angular 1, где все единицы DI были аннотированы как строки).

+0

Благодарим за отзыв. Я попытаюсь интегрировать это в решение, над которым я сейчас работаю. – Edward

+0

@DeveloperWonk Нет, есть необходимость. См. Https: // stackoverflow.com/a/39522406/3731501 – estus

Смежные вопросы