2016-02-22 12 views
6

Buduję moduł modalny w Angular 2 (i TypeScript), który będzie miał różne widoki/strony. Nie będzie miał kart, ale koncepcja jest bardzo podobna. Zasadniczo staram się znaleźć sposób na zrobienie tego.Tablica wyjściowa komponentów w Angular 2

W ramach mojego komponentu modalnego chcę wyprowadzać różne widoki/strony. Każdy powinien być samym komponentem, ponieważ nie ma żadnych wspólnych znaków. Dodatkowo będą pobierać dane z klas usług, więc muszę mieć możliwość napisania określonej logiki dla każdego widoku.

Zasadniczo czego chcę jest coś takiego:

// Within my modal component's template 
<div *ngFor="#view of views"> 
    // Render view component here 
</div> 

Gdzie views mogłoby być tablicą z elementów, na przykład. Mój pierwszy i główny problem polega na tym, że nie jestem pewien, jak wyświetlić zbiór moich widoków (komponentów).

Jak mogę wypisać kolekcję komponentów w ramach innego komponentu?

Potrzebuję również sposobu na ukrycie i przedstawienie poglądów, co jest jedyną rzeczą, która ma wspólne poglądy. Zastanawiałem się nad dodaniem zmiennej isActive do widoków i pokazywania/ukrywania ich na podstawie tego. Czy dla komponentów widoków może być niekorzystna praktyka implementacja interfejsu ModalView lub rozszerzenie z klasy bazowej w celu dodania tej logiki? Z mojego modalnego komponentu chcę mieć możliwość kontrolowania, który widok jest wyświetlany, więc potrzebuję widoków, aby ta logika była wspólna.

Mam nadzieję, że jest jasne, co chcę zrobić. Rozwiązanie może być proste, ale teraz jestem nieco zdezorientowany, jak to zrobić. Przykład kodu byłby bardzo doceniany!

Odpowiedz

4

Można utworzyć "fabrykę komponentów" jako dyrektywę, która ładuje odpowiednie komponenty za pomocą DynamicComponentLoader, w oparciu o parametry przekazywane z modalu.

<component-factory *ngFor="#view of views" 
    (loaded)="addComponent($event)" 
    [name]="view.name" 
    [visible]="view.visible"></component-factory> 

@Directive({ selector: 'component-factory' }) 
class ComponentFactory { 
    @Input() name; 
    @Input() visible; 
    @Output() loaded = new EventEmitter(); 
    constructor(
    private _dcl: DynamicComponentLoader, 
    private _eref: ElementRef) { 

    // import OneCmp, TwoCmp in this file... 
    private components: { one: OneCmp, two: TwoCmp } 

    ngOnInit() { 
    this._dcl.loadNextToLocation(
     this.components[this.name], 
     this._eref) 
     // pass values to the loaded components 
     // and send it's instance to the parent 
     .then((ref: ComponentRef) => { 
     ref.instance.visible = this.visible; 
     this.loaded.emit(ref.instance) 
     }); 
    } 
} 
+0

Och, to wygląda super, wielkie dzięki! Myślę, że na wypadek, gdyby potrzebowałem dalszej interakcji z moimi poglądami, mógłbym chcieć wyciągnąć kod z dyrektywy i osadzić tę logikę w składniku modalnym (lub przynajmniej nawiązać do tamtejszej fabryki), ponieważ wtedy mogę zachować odniesienia do załadowanych komponentów. Jeśli masz jakieś opinie na temat tego podejścia, bardzo chciałbym to usłyszeć. Niemniej jednak, teraz mam bardzo przydatny kod referencyjny, więc kciuki w górę za to! – Andy0708

+0

Myślałem, że dyrektywa będzie bardziej przydatna do ponownego użycia. Możesz wysłać referencję do komponentu nadrzędnego poprzez '@Output()', emitując '(ref: ComponentRef)' i zbierając je w modalu. – Sasxa

+0

Zaktualizowano kod ... – Sasxa

1

Angular2 Dynamicznie Render Szablon

import { Component, View, DynamicComponentLoader, ElementRef} from 'angular2/core'; import {bootstrap} from 'angular2/platform/browser' 

@Component({ 
    selector: 'some-component', 
    properties: ['greeting'], 
    template: ` 
    <b>{{ greeting }}</b> 
    ` 
}) 
class SomeComponent { } 




@Component({ 
    selector: 'app' 
}) 
@View({ 
    template: ` 
    <h1>Before container</h1> 
    <div #container></div> 
    <h2>After container</h2> 
    ` 
}) 
class App { 
    loader: DynamicComponentLoader; 
    elementRef: ElementRef; 

    constructor(loader: DynamicComponentLoader, elementRef: ElementRef) { 
    this.laoder = loader; 
    this.elementRef = elementRef; 

    // Some async action (maybe ajax response with html in it) 
    setTimeout(() => this.renderTemplate(` 
     <div> 
    <h2>Hello</h2> 
    <some-component greeting="Oh, hey"></some-component> 
     </div> 

pełny kod: https://github.com/guyoung/GyPractice-Angular2Advanced/tree/master/apps/dynamically_render_template