2016-07-12 26 views
7

È possibile identificare se un componente Angular2 (qui AppComponent) è completamente caricato (incluso ViewChilds) quando vi è ngIf nel modello che condizionatamente carica il bambino.Come identificare se un componente Angular2 è completamente caricato (incluso ViewChilds) quando c'è ngIf nel modello

Riferimento: Angular 2 @ViewChild annotation returns undefined Questo esempio è tratto dal riferimento precedente. Grazie alla kenecaswell

import {Component, ViewChild, OnInit, AfterViewInit} from 'angular2/core'; 
import {ControlsComponent} from './child-component-1'; 
import {SlideshowComponent} from './slideshow/slideshow.component'; 

@Component({ 
    selector: 'app', 
    template: ` 
     <div *ngIf="controlsOn"> 
      <controls ></controls> 
      <slideshow></slideshow> 
     </div> 
    `, 
    directives: [SlideshowComponent, ControlsComponent] 
}) 

export class AppComponent { 
    @ViewChild(ControlsComponent) controls:ControlsComponent; 
    @ViewChild(SlideshowComponent) slide:SlideshowComponent; 

    controlsOn:boolean = false; 

    ngOnInit() { 
     console.log('on init', this.controls); 
     // this returns undefined 
    } 

    ngAfterViewInit() { 
     console.log('on after view init', this.controls); 
     // this returns null 
    } 

} 

Il ngOnInit & & ngAfterViewInit sono licenziati prima che i componenti del bambino vengono caricati a causa della condizione ngIf

ho bisogno di identificare quando SlideshowComponent & ControlsComponent vengono caricate ed eseguire un'azione basata su questo.

Ho una soluzione hacky che non è adatta quando ci sono più ViewChild (che sono di tipo diverso) - Utilizzo di un emettitore di eventi per informare quando il bambino è caricato.

Sto postando questa domanda poiché non c'erano soluzioni adeguate dopo ore di ricerca.

risposta

1

PLUNKER

Prova ViewChildren invece ViewChild, che fornisce un changes osservabile, possiamo usare come un gancio.

seguire tutto il ViewChildren, è possibile unire i loro changes osservabili in un unico e registrarsi al sito, quindi si ottiene un unico punto d'azione, come questo

@ViewChildren(ChildCmp) children: QueryList<ChildCmp>; 
    @ViewChildren(AnotherChildCmp) anotherChildren: QueryList<ChildCmp>; 

    childrenDetector: Observable<any>; // merged observable to detect changes in both queries 

    ngAfterViewInit(){ 
    this.childrenDetector = Observable.merge(this.children.changes, this.anotherChildren.changes) 

    this.childrenDetector.subscribe(() => { 

     // here you can even check the count of view children, that you queried 
     // eg: if(this.children.length === 1 && this.anotherChildren.length === 1) { bothInitialized(); } 
     // or something like that 

     alert('you just initialized a children'); 
    }); 
    } 
} 
+0

Ciao, il mio problema è che ho 3 componenti (ViewChild) di diverso tipo e voglio identificare quando tutti e tre i componenti (ViewChild) sono caricati ed eseguire un'azione. Ho aggiornato la domanda. Grazie – tymspy

+0

Sono su di esso, fammi vedere cosa posso fare .... –

+1

OK, il problema è causato da '* ngIf' non lasciare inizializzare i componenti figli su ViewInit, ora 'ViewChildren' ha ancora più senso, perché può dirti quando i bambini inizializzano, vedi [questo PLUNKER] (http://plnkr.co/edit/HevkaqUyqmkAnvgPwm7v?p=preview) –

1

Puoi avvolgere roba in * ngIf modo che html non mostrerà nulla fino a quando non è finito tutto.

<div *ngIf="loaded"> 
    /* all codes go here */ 
<div> 

OnInit(){ 
    foo(); 
    bar(()=>{ 
     this.loaded = true; 
    }); 
}