2017-03-01 17 views
12

W kątowe 4 do dynamicznego tworzenia komponentu można użyć ngComponentOutlet dyrektywy: https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.htmlkątowe 4+ przypisać @Input dla ngComponentOutlet dynamicznie utworzony komponent

coś takiego:

dynamiczny składnik

@Component({ 
    selector: 'dynamic-component', 
    template: ` 
    Dynamic component 
    ` 
}) 
export class DynamicComponent { 
    @Input() info: any; 
} 

Aplikacja

@Component({ 
    selector: 'my-app', 
    template: ` 
    App<br> 
    <ng-container *ngComponentOutlet="component"></ng-container> 
    ` 
}) 
export class AppComponent { 
    this.component=DynamicComponent; 
} 

Jak przekazać informacje @Input() info: any; w tym szablonie <ng-container *ngComponentOutlet="component"></ng-container>?

+0

Co '@ Input'? . –

+1

w jaki sposób wysyłasz informacje do dynamicznie tworzonego komponentu z szablonu? Czy korzystasz z dekoratorów @Input lub z czegoś innego? –

+1

to zależy od tego, jakie informacje, skąd i co masz na myśli przez "z szablonu". Jeśli potrzebujesz wsparcia, musisz podać więcej szczegółów. –

Odpowiedz

6

Taka funkcja została omówiona w żądaniu pobrania dla ngComponentOutlet, ale została na razie odrzucona. Nawet componentRef pokazano obecnie https://angular.io/docs/ts/latest/api/common/index/NgComponentOutlet-directive.html nie jest publiczna, a zatem nie ma możliwości https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L78

sugeruję stworzyć własną dyrektywę pochodzący z https://github.com/angular/angular/blob/3ef73c2b1945340ca6bd21f1790260c88698ae26/modules/%40angular/common/src/directives/ng_component_outlet.ts#L72

i przypisać wartości do wejść jak pokazano na Angular 2 dynamic tabs with user-click chosen components

this.compRef.instance.someProperty = 'someValue'; 
+0

Dzięki. Czy możliwe jest posiadanie innego ngComponentOutlet przed wydaniem wersji v4.0? Mam na myśli pewne opcje, które poradzą sobie z tym problemem? –

+0

Nie wiem o planach. Wniosek był taki, że wspieranie wejść jest zbyt skomplikowane dla pierwszej wersji i że chcą ją wydać tak jak jest, a następnie ostatecznie podejść do tego problemu ponownie, ale od tego czasu nie widziałem powiązanych dyskusji (co nie znaczy wiele, ponieważ masz dużo czasu na sprawdzenie) –

+0

@ GünterZöchbauer Tak więc, jeśli wywołuję komponent dynamicznie za pomocą 'ngComponentOutlet', jedynym sposobem na wysłanie' modelu' lub 'danych' z mojego bieżącego szablonu/komponentu do komponentu dynamicznego jest utworzenie niestandardowe dyrektywy lub korzystające z jakiegoś rodzaju usługi? 'ngComponentOutlet'nie nie ma żadnej wbudowanej funkcji komunikowania obu składników: wywołującego i wywoływanego? Nawet 'ngComponentOutletInjector'? – SrAxi

6

Z pomocą postu @ Güntera Zöchbauera rozwiązałem podobny problem w ten sposób - mam nadzieję, że jakoś go dostosujesz.

Najpierw określono pewne interfejsy:

// all dynamically loaded components should implement this guy 
export interface IDynamicComponent { Context: object; } 

// data from parent to dynLoadedComponent 
export interface IDynamicComponentData { 
    component: any; 
    context?: object; 
    caller?: any; 
} 

potem realizowane je wewnątrz dynamicznie załadowanego składnika

dynamicLoadedComponentA.ts

// ... 
export class DynamicLoadedComponentA implements IDynamicComponent { 
// ... 

// data from parent 
public Context: object; 

// ... 

Potem zbudował nowy komponent odpowiedzialny za magię. Ważne jest to, że musiałem zarejestrować wszystkie dyn. załadowane komponenty jako entryComponents.

dynamic.component.ts

@Component({ 
    selector: 'ngc-dynamic-component', 
    template: ´<ng-template #dynamicContainer></ng-template>´, 
    entryComponents: [ DynamicLoadedComponentA ] 
}) 
export class DynamicComponent implements OnInit, OnDestroy, OnChanges { 
    @ViewChild('dynamicContainer', { read: ViewContainerRef }) public dynamicContainer: ViewContainerRef; 

    @Input() public componentData: IDynamicComponentData; 

    private componentRef: ComponentRef<any>; 
    private componentInstance: IDynamicComponent; 

    constructor(private resolver: ComponentFactoryResolver) { } 

    public ngOnInit() { 
    this.createComponent(); 
    } 

    public ngOnChanges(changes: SimpleChanges) { 
    if (changes['componentData']) { 
     this.createComponent(); 
    } 
    } 

    public ngOnDestroy() { 
    if (this.componentInstance) { 
     this.componentInstance = null; 
    } 
    if (this.componentRef) { 
     this.componentRef.destroy(); 
    } 
    } 

    private createComponent() { 
    this.dynamicContainer.clear(); 
    if (this.componentData && this.componentData.component) { 
     const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(this.componentData.component); 
     this.componentRef = this.dynamicContainer.createComponent(factory); 
     this.componentInstance = this.componentRef.instance as IDynamicComponent; 

     // fill context data 
     Object.assign(this.componentInstance.Context, this.componentData.context || {}); 

     // register output events 
     // this.componentRef.instance.outputTrigger.subscribe(event => console.log(event)); 
    } 
    } 
} 

tutaj wykorzystanie tego błyszczącą nowych rzeczy:

app.html

<!-- [...] --> 
<div> 
    <ngc-dynamic-component [componentData]="_settingsData"></ngc-dynamic-component> 
</div> 
<!-- [...] --> 

aplikacja.ts

// ... 
    private _settingsData: IDynamicComponent = { 
    component: DynamicLoadedComponentA, 
    context: { SomeValue: 42 }, 
    caller: this 
    }; 
// ... 
+0

czy to rozwiązanie działa z kompilacją z wyprzedzeniem? –

+1

Obecnie nie testowałem z AOT, ale spróbuję przetestować to w niedalekiej przyszłości i uzupełnić mój post. –

Powiązane problemy