How Do We Detect Component Initialization? [SOLVED]


#1

For example, I want to disable swipe on my side menu, but this can’t be done until the side menu’s ngOnInit method has fired.

@brandyshea I saw you gave this example in issue 5390

import {MenuController} from 'ionic/ionic';

constructor(menu: MenuController) { this.menu = menu; let menuOpen = this.menu.get().isOpen; console.log( menuOpen ); }

In my experience, the MenuController is useless in the constructor of the page, because the menu components have not yet registered themselves with the MenuController. I’ve tested onPageLoaded and onPageDidEnter lifecycle hooks too, and they are no good. The only thing that works for me is to create a setTimeout and wait a few ticks for the MenuController to have its _menu array populated with the menu components on the page.

Would love some advice on this. Seems like a fundamental requirement.Thanks!


#2

I should note that my page contains some very heavy DOM initialization (canvas tag with expensive GPU operations). This might make my page take a lot longer to initialize than a regular page, which is why I really need to explicitly hook into component init events.

This is what I’m currently doing (Ionic 2, beta 4):

import {MenuController} from 'ionic-angular';
import {AppPage} from '../../util/app.page.class';

@Page({
    templateUrl: 'build/pages/adventure/mypage.html'
})
export class MyPage extends AppPage {

    static get parameters() {
        return [[MenuController]];
    }

    constructor(menuCtrl) {
        super();
        this.menuCtrl = menuCtrl;  

        //Expensive DOM init starts here      
    }

    onPageDidEnter() {
        //doesn't work :(
        this.menuCtrl.swipeEnable(false, 'my-menu');
    }

    onPageLoaded() {
        //doesn't work :(
        this.menuCtrl.swipeEnable(false, 'my-menu');

        setTimeout(()=>{
            //Works! :)
            this.menuCtrl.swipeEnable(false, 'my-menu');
        }, 1000);        
    }
}

#3

You might want to look at afterViewInits

https://angular.io/docs/ts/latest/api/core/AfterViewInit-interface.html


#4

this called life cycle of an component/directives.

in angular 2 you have life cycle hooks you can import from angular2/core

This are interfaces you can implement in your component class.
If you want to wait until all subviews (child components are ready and their dom are rendered, too) use mikes approach AfterViewInit.

import {OnAfterViewInit} from 'angular2/core';

@component({...})
export class test implements OnAfterViewInit {
  ngOnAfterViewInit() {
     // DO IT
  }
}

I did not test this code but i think you can get an idea how it works.


#5

Thanks @mhartington, that’s exactly what I need!


#6

@bengtler thanks, but it turns out you don’t need to import or implement the interface when using JavaScript (maybe you need to for TypeScript, I’m not sure).

All I had to do was add this to my class and it gets correctly called after the view is fully initialized.

ngAfterViewInit() {
    this.menuCtrl.swipeEnable(false, 'my-menu');
}

#7

It’s good practice anyway. That way static code analysis can warn you if you make stupid capitalization or spelling mistakes in the method name.


#8

@rapropos is it possible to implement interfaces using JavaScript? From my initial research, es6 doesn’t support interfaces, only TypeScript does.


#9

I believe that interface and implements are considered “future reserved words” by ES6, so they would probably error in strict mode. I’m not sure what would happen in non-strict mode.