Xav
Xav

Reputation: 23

How to navigate into an Ionic 2 app

I'm trying to do a small app in Ionic 2 but I can't manage to navigate... I have read the documentation, navigation stuff, navController, some post on StackOverflow... I tried for hours but I'm stuck ! I had several issues.

I had to find a way to use navController into my app.js, which I did thanks to @viewChild and StackOF. I don't fully understand the principle. I set rootPage: any = Login;. As I have a menu on my app, I disabled it on this page. On a button (click), I set the root this.nav.setRoot() with HomePage. Now from the HomePage, within the menu, I want to navigate through some pages. I'm stuck here. I used the (click)="openPage(Messagerie)" method. First issue, the parameter in openPage() is undefined. Then I tried the [navPush]="pageMessagerie" and this.pageMessagerie = Messagerie; method following the documentation, but it didn't works as well, nothing happen. So, I tried to hard-code the page into my openPage() function : this.nav.push(Messagerie);. Here I have another issue again. The first time I call the push(), the page seems to appear and disappear immediately, coming back on the HomePage. The second time I click, it seems to work. I can go on the Messagerie page and come back on the HomePage via the back button on the navbar.

So... Here I am, stuck with the navigation ! I don't know what to do. Here is my code.


Update Ok the undefined is ok now. But my nav still act weird. When I use this.nav.push() on the home page I got this workflow : Click on Messagerie : Open Messagerie and immediately back on Home Page. Click on Demandes : Open Messagerie, immediately Demandes and stay there. Click on navbar back button : Back to Messagerie, back to Demandes and back to Home Page. Of course if I use this.nav.setRoot() each time it works but I lose the nav principle.


App.html

<ion-menu [content]="content">
    <ion-toolbar>
        <ion-title>Menu</ion-title>
    </ion-toolbar>
    <ion-content>
        <ion-list>
            <button ion-item menuToggle = "left">
                Mes informations
            </button>
            <button ion-item menuToggle = "left" (click)="openPage(Messagerie)">
                Ma messagerie
            </button>
            <button ion-item menuToggle = "left" (click)="openPage(Demandes)">
                Mes demandes
            </button>
        </ion-list>
    </ion-content>
</ion-menu>

<ion-nav id="nav" #content [root]="rootPage"></ion-nav>

App.ts

import {Component, ViewChild}  from '@angular/core';
import {Platform, ionicBootstrap, NavController} from 'ionic-angular';
import {StatusBar}  from 'ionic-native';
import {HomePage}   from './pages/home/home';
import {Messagerie} from './pages/messagerie/messagerie';
import {Demandes}   from './pages/demandes/demandes';
import {Login}      from './pages/login/login';

@Component({
    templateUrl: 'build/app.html' 
})

export class MyApp {

    @ViewChild('content') nav

    rootPage: any = Login;

    constructor(private platform: Platform) {
        platform.ready().then(() => {
            StatusBar.styleDefault();
        });
    }

    openPage(page) {
        console.log(page);
        this.nav.push(page);
    }
}

ionicBootstrap(MyApp);

Login.ts (with the setroot)

import {Component}      from '@angular/core';
import {NavController, MenuController}  from 'ionic-angular';
import {FormBuilder, ControlGroup, Validators} from '@angular/common';
import {HomePage}       from '../home/home';

@Component({
    selector: 'mc-login',
    templateUrl: 'build/pages/login/login.html'
})
export class Login {

    loginForm: ControlGroup;

    loginChanged:       boolean = false;
    motdepasseChanged:  boolean = false;
    submitAttempt:      boolean = false;

    constructor(private nav: NavController, private formBuilder: FormBuilder, private menu: MenuController) {
        this.menu.enable(false);
        this.loginForm = formBuilder.group({
            login: ['', Validators.compose([Validators.maxLength(10), Validators.pattern('[a-zA-Z ]*'), Validators.required])],
            motdepasse: ['', Validators.compose([Validators.maxLength(10), Validators.pattern('[a-zA-Z ]*'), Validators.required])]
        });
    }

    elementChanged(input) {
        let field = input.inputControl.name;
        this[field+"Changed"] = true;
    }

    logintoapp() {
        this.submitAttempt = true;

        if(this.loginForm.valid) {
            this.logindatabase();
        } else {
            console.log("Nope");
        }    
    }

    logindatabase() {
        this.nav.setRoot(HomePage);
    }
}

Do I miss something ? What am I doing wrong ? Thanks a lot for your help !

Upvotes: 1

Views: 3464

Answers (2)

David Dal Busco
David Dal Busco

Reputation: 8652

Could you try this:

In app.ts, declare the nav and following array as following:

@ViewChild(Nav) nav:Nav;

browsePages:Array<{title:string, component:any}>;

add to your constructor (this is just need to explicitly close the menu later):

private menu: MenuController

inside your constructor declare your pages you want to add to your menu:

this.browsePages = [
        {title: 'Ma messagerie', component: Messagerie},
        {title: 'Mes demandes', component: Demandes}
    ];

replace your buttons "Ma messagerie" et "Mes demandes" in html like following:

<button ion-item *ngFor="let p of browsePages" (click)="openPage(p)">
   {{p.title}}
</button>

and then finally your openPage method:

openPage(page) {
    // close the menu when clicking a link from the menu
    this.menu.close();
    // navigate to the new page if it is not the current page
    this.nav.setRoot(page.component);
}

That was for the navigation from the menu.

Now about the navigation from the login page...replace your setroot with a navigation push. Generally speaking, except when you really need to set the root you should, I think, push pages in the stack to navigate not set the root again. So basically use push and pop on the navcontroller to navigate.

*** UPDATE to go to the next page and removing current one from history

logindatabase() {
    this.goToNextPageWithoutBack(HomePage);
}

private goToNextPageWithoutBack(page:any, params?:any) {
    this.nav.push(page, params).then(() => {
        this.removeCurrentViewFromHistory();
    });
}

private removeCurrentViewFromHistory() {
    const index = this.nav.getActive().index;
    this.nav.remove(0, index);
}

**** UPDATE

And then to display the menu toggle in your homepage.html add

<ion-header>
<ion-navbar>

<button menuToggle start>
  <ion-icon name="ios-menu-outline"></ion-icon>
</button>

<ion-title>my-items</ion-title>
</ion-navbar>
</ion-header> 

I tried to extract these lines from my working codes, hope it gonna help you.

Upvotes: 3

tothefux
tothefux

Reputation: 223

You need to set your scope variables to the actual pages. Right now the (click)="openPage(Messagerie)" --> Messagerie being passed in is undefined. You need to set this.Messagerie = Messagerie in your component.

Upvotes: 0

Related Questions