ionic 2 sidemenu - navCtrl inside a component

2019-09-11 01:49发布

问题:

I'm using the ionic 2 starter template with sidemenu.

So the original app.html looks like this

<ion-menu [content]="content">
    <ion-toolbar>
        <ion-title>Menu</ion-title>
    </ion-toolbar>

    <ion-content>
        <ion-list>
            <button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
                {{p.title}}
            </button>
        </ion-list>
    </ion-content>
</ion-menu>

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

and I want to replace the menu content with a component like this

<ion-menu [content]="content">
    <st-menu></st-menu>
</ion-menu>

my menu.component.ts looks like this, which is basically copied from the original app.ts file

import {Page1} from "../pages/page1/page1";
import {Page2} from "../pages/page2/page2";
import {Nav, NavController} from "ionic-angular";

@Component({
    selector: 'st-menu',
    templateUrl: 'build/menu/menu.html'
})

export class MenuCmp {
    @ViewChild(Nav) nav: Nav;

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

    constructor(private navCtrl:NavController) {
        this.pages = [
            { title: 'Home', component: HomePage },
            { title: 'Page uno', component: Page1 },
            { title: 'Page dos', component: Page2 }
        ];
    }
    openPage(page) {
        this.nav.setRoot(page.component);
    }

}

and menu.html like this

<ion-toolbar>
    <ion-title>Menu</ion-title>
</ion-toolbar>

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

Now when I click inside the menu I've getting an error:

Cannot read property 'setRoot' of undefined

I've tested by replacing this.nav.setRoot(page.component) with this.nav.setRoot(HomePage); and it still the same. When I replace nav with navCtrl (provided and injected) it says this.navCtrl.setRoot is not a function

Any suggestions? Thanks!

回答1:

You should try passing the navCtrl of the parent component to the openPage function, From ionic docs :

Injecting NavController will always get you an instance of the nearest NavController, regardless of whether it is a Tab or a Nav.

Behind the scenes, when Ionic instantiates a new NavController, it creates an injector with NavController bound to that instance (usually either a Nav or Tab) and adds the injector to its own providers. For more information on providers and dependency injection, see Providers and DI.

they also say :

What if you want to control navigation from your root app component? You can't inject NavController because any components that are navigation controllers are children of the root component so they aren't available to be injected.

By adding a reference variable to the ion-nav, you can use @ViewChild to get an instance of the Nav component, which is a navigation controller (it extends NavController):

You don't have a navCtrl to inject but you have at menu.ts :

@ViewChild(Nav) nav: Nav;

But you don't have an ion-nav as a viewChild at menu.html You can either pass the navCtrl from the app.ts to the component as an input , or find a way to wrap the ion-nav in menu.html, you could also just declare the openPage function at the app.ts level, then pass it to the component as an Input (but use the arrow notation when you declare the function to keep the this scope)