Как динамически загружать компонент, используя имя компонента в angular2?

В настоящее время я загружаю компоненты angular динамически в мое приложение, используя следующий код.

export class WizardTabContentContainer {
  @ViewChild('target', { read: ViewContainerRef }) target: any;
  @Input() TabContent: any | string;
  cmpRef: ComponentRef<any>;
  private isViewInitialized: boolean = false;

  constructor(private componentFactoryResolver: ComponentFactoryResolver,   private compiler: Compiler) {
  }

  updateComponent() {
     if (!this.isViewInitialized) {
       return;
     }
     if (this.cmpRef) {
       this.cmpRef.destroy();
     }
     let factory = this.componentFactoryResolver.resolveComponentFactory(this.TabContent);

     this.cmpRef = this.target.createComponent(factory);
   }
}

Здесь функция resolveComponentFactory принимает тип компонента. Мой вопрос: есть ли способ загрузить компонент, используя строку имени компонента, например, у меня есть компонент, определенный как

export class MyComponent{
}

Как добавить компонент выше с использованием имени компонента "MyComponent" вместо типа?

Ответ 1

Возможно, это сработает

import { Type } from '@angular/core';

@Input() comp: string;
...
var factories = Array.from(this.resolver['_factories'].keys());
var factoryClass = <Type<any>>factories.find((x: any) => x.name === this.comp);
const factory = this.resolver.resolveComponentFactory(factoryClass);
const compRef = this.vcRef.createComponent(factory);

где this.comp - это строковое имя вашего компонента, например "MyComponent"

Пример плунжера

Чтобы сделать это, работая с минификацией, см.

Ответ 2

Также можно получить доступ через import:

import * as possibleComponents from './someComponentLocation'
...
let inputComponent = possibleComponents[componentStringName];

то вы можете создать экземпляр компонента, например:

if (inputComponent) {
    let inputs = {model: model};
    let inputProviders = Object.keys(inputs).map((inputName) => { return { provide: inputName, useValue: inputs[inputName] }; });
    let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
    let injector: ReflectiveInjector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicInsert.parentInjector);
    let factory = this.resolver.resolveComponentFactory(inputComponent as any);
    let component = factory.create(injector);
    this.dynamicInsert.insert(component.hostView);
}

Обратите внимание, что компонент должен находиться в @NgModule entryComponents