Is it possible to Identify whether a Angular2 component (here AppComponent) is completely loaded ( including ViewChilds ) when there ngIf in template which conditionally loads the child.
Reference: Angular 2 @ViewChild annotation returns undefined This example is taken from the above reference. Thanks to 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
}
}
The ngOnInit && ngAfterViewInit are fired before the the child components are loaded because of the ngIf condition
I need identify when SlideshowComponent & ControlsComponent are loaded and perform an action based on that.
I have a hacky solution which is not suitable when there are multiple ViewChilds (Which are of different type) - Using an event emitter to inform when the child is loaded.
I'm posting this question since there were no proper solution after hours of research.
PLUNKER
Try ViewChildren
instead of ViewChild
, which provides a changes
Observable, we can use as a hook.
To track all the ViewChildren, you can merge their changes
Observables into one and subscribe to it, then you get single point of action, like this
@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');
});
}
}
You can wrap stuff in *ngIf so that html won't show anything untill ngOnInit finished all.
<div *ngIf="loaded">
/* all codes go here */
<div>
OnInit(){
foo();
bar(()=>{
this.loaded = true;
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With