2016-10-18 19 views
10

Aktualnie ładuję komponenty kątowe dynamicznie w mojej aplikacji przy użyciu następującego kodu.Jak ładować komponent dynamicznie za pomocą nazwy komponentu w angular2?

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

Tutaj funkcja resolveComponentFactory akceptuje typ komponentu. Moje pytanie brzmi: Czy jest jakiś sposób mogę załadować komponent używając nazwa składnika ciąg np mam komponent zdefiniowany jako

export class MyComponent{ 
} 

Jak mogę dodać powyżej komponentu przy użyciu nazwy komponentu ciąg „MyComponent” zamiast typu?

Odpowiedz

14

Być może będzie to działać

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

gdzie this.comp to nazwa ciąg komponentu jak "MyComponent"

Plunker Example

Aby to zrobić pracę z minifikacji zobaczyć

+0

Jego błąd rzucania na x.name. Nazwa właściwości "nie istnieje" w typie "{}". –

+0

Zaktualizowałem odpowiedź – yurzui

+2

Dzięki. Rozwiązałem błąd w powyższym komentarzu przy użyciu fabryki.find (x => x ['name'] === this.comp); jednak teraz pojawia się błąd Argumentu typu "{}" nie można przypisać parametrowi typu "Typ <{}>". Brak właściwości "apply" w typie "{}". on line const factory = this.resolver.resolveComponentFactory (factoryClass); –

0

Możliwe jest również, aby uzyskać dostęp poprzez importu:

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

następnie można utworzyć instancję składnika na przykład:

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

zauważyć, że składnik ma być w @ NgModule entryComponents

Powiązane problemy