fix(nav): ionViewDidLoad fires before children components have been loaded

fixes #8449
This commit is contained in:
Manu Mtz.-Almeida
2016-10-24 23:12:07 +02:00
parent 6484c501fa
commit e89f3b0206
2 changed files with 57 additions and 9 deletions

View File

@ -1,11 +1,20 @@
import { NgModule, Component, ViewChild } from '@angular/core'; import { NgModule, Component, ViewChild } from '@angular/core';
import { App, AlertController, Content, DeepLinkConfig, IonicApp, IonicModule, NavController, NavParams, Tabs, Tab, ModalController, ViewController } from '../../../..'; import { App, AlertController, Content, DeepLinkConfig, IonicApp, IonicModule, Label, NavController, NavParams, Tabs, Tab, ModalController, ViewController } from '../../../..';
@Component({ @Component({
selector: 'my-cmp', selector: 'my-cmp',
template: `<p>My Custom Component Test <ion-icon name="star"></ion-icon></p>` template: `<ion-label>My Custom Component Test <ion-icon name="star"></ion-icon>
<span style="color:green">{{value}}</span></ion-label>`
}) })
export class MyCmpTest {} export class MyCmpTest {
@ViewChild(Label) _label: Label;
label: Label;
value: string = '';
ngOnInit() {
this.label = this._label;
}
}
@Component({ @Component({
@ -22,6 +31,16 @@ export class MyCmpTest {}
</ion-navbar> </ion-navbar>
</ion-header> </ion-header>
<ion-content> <ion-content>
<div padding>
<p>ionViewCanEnter ({{called.ionViewCanEnter}})</p>
<p>ionViewCanLeave ({{called.ionViewCanLeave}})</p>
<p>ionViewDidLoad ({{called.ionViewDidLoad}})</p>
<p>ionViewWillEnter ({{called.ionViewWillEnter}})</p>
<p>ionViewDidEnter ({{called.ionViewDidEnter}})</p>
<p>ionViewWillLeave ({{called.ionViewWillLeave}})</p>
<p>ionViewDidLeave ({{called.ionViewDidLeave}})</p>
<my-cmp></my-cmp>
</div>
<ion-list> <ion-list>
<ion-list-header> <ion-list-header>
{{title}} {{title}}
@ -53,7 +72,6 @@ export class MyCmpTest {}
<button ion-item *ngFor="let i of pages" (click)="pushPrimaryHeaderPage()">Page {{i}}</button> <button ion-item *ngFor="let i of pages" (click)="pushPrimaryHeaderPage()">Page {{i}}</button>
<button ion-item (click)="content.scrollToTop()">Scroll to top</button> <button ion-item (click)="content.scrollToTop()">Scroll to top</button>
</ion-list> </ion-list>
<my-cmp></my-cmp>
</ion-content>` </ion-content>`
}) })
export class FirstPage { export class FirstPage {
@ -61,39 +79,62 @@ export class FirstPage {
title = 'First Page'; title = 'First Page';
pages: Array<number> = []; pages: Array<number> = [];
@ViewChild(Content) content: Content; @ViewChild(Content) content: Content;
@ViewChild(MyCmpTest) myCmp: MyCmpTest;
canLeave = true; canLeave = true;
called: any;
constructor( constructor(
public navCtrl: NavController, public navCtrl: NavController,
public viewCtrl: ViewController, public viewCtrl: ViewController,
public alertCtrl: AlertController public alertCtrl: AlertController
) {} ) {
this.called = {
ionViewCanEnter: 0,
ionViewCanLeave: 0,
ionViewDidLoad: 0,
ionViewWillEnter: 0,
ionViewDidEnter: 0,
ionViewWillLeave: 0,
ionViewDidLeave: 0
};
}
ionViewDidLoad() { ionViewDidLoad() {
console.log('ionViewDidLoad, FirstPage'); console.log('ionViewDidLoad, FirstPage');
for (var i = 1; i <= 50; i++) { for (var i = 1; i <= 50; i++) {
this.pages.push(i); this.pages.push(i);
} }
if (!this.myCmp || !this.content || !this.myCmp.label) {
throw new Error('children are not loaded');
}
this.myCmp.value = 'root!';
this.myCmp.label.color = 'primary';
this.called.ionViewDidLoad++;
} }
ionViewWillEnter() { ionViewWillEnter() {
console.log('ionViewWillEnter, FirstPage', this.viewCtrl.id); console.log('ionViewWillEnter, FirstPage', this.viewCtrl.id);
this.called.ionViewWillEnter++;
} }
ionViewDidEnter() { ionViewDidEnter() {
console.log('ionViewDidEnter, FirstPage', this.viewCtrl.id); console.log('ionViewDidEnter, FirstPage', this.viewCtrl.id);
this.called.ionViewDidEnter++;
} }
ionViewWillLeave() { ionViewWillLeave() {
console.log('ionViewWillLeave, FirstPage', this.viewCtrl.id); console.log('ionViewWillLeave, FirstPage', this.viewCtrl.id);
this.called.ionViewWillLeave++;
} }
ionViewDidLeave() { ionViewDidLeave() {
console.log('ionViewDidLeave, FirstPage', this.viewCtrl.id); console.log('ionViewDidLeave, FirstPage', this.viewCtrl.id);
this.called.ionViewDidLeave++;
} }
ionViewWillUnload() { ionViewWillUnload() {
console.log('ionViewWillUnload, FirstPage', this.viewCtrl.id); console.log('ionViewWillUnload, FirstPage', this.viewCtrl.id);
this.called.ionViewWillUnload++;
} }
ionViewCanLeave() { ionViewCanLeave() {
@ -106,9 +147,16 @@ export class FirstPage {
alert.addButton({ text: 'Umm, ok', role: 'cancel', }); alert.addButton({ text: 'Umm, ok', role: 'cancel', });
alert.present(); alert.present();
this.called.ionViewCanLeave++;
return false; return false;
} }
ionViewCanEnter() {
this.called.ionViewCanEnter++;
return true;
}
setPages() { setPages() {
let items = [ let items = [
{ page: PrimaryHeaderPage } { page: PrimaryHeaderPage }

View File

@ -425,10 +425,6 @@ export class NavControllerBase extends Ion implements NavController {
_viewAttachToDOM(view: ViewController, componentRef: ComponentRef<any>, viewport: ViewContainerRef) { _viewAttachToDOM(view: ViewController, componentRef: ComponentRef<any>, viewport: ViewContainerRef) {
assert(view._state === ViewState.INITIALIZED, 'view state must be INITIALIZED'); assert(view._state === ViewState.INITIALIZED, 'view state must be INITIALIZED');
// successfully finished loading the entering view
// fire off the "didLoad" lifecycle events
this._didLoad(view);
// render the component ref instance to the DOM // render the component ref instance to the DOM
// ******** DOM WRITE **************** // ******** DOM WRITE ****************
viewport.insert(componentRef.hostView, viewport.length); viewport.insert(componentRef.hostView, viewport.length);
@ -443,6 +439,10 @@ export class NavControllerBase extends Ion implements NavController {
} }
componentRef.changeDetectorRef.detectChanges(); componentRef.changeDetectorRef.detectChanges();
// successfully finished loading the entering view
// fire off the "didLoad" lifecycle events
this._didLoad(view);
} }
_viewTest(enteringView: ViewController, leavingView: ViewController, ti: TransitionInstruction) { _viewTest(enteringView: ViewController, leavingView: ViewController, ti: TransitionInstruction) {