Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ionic 2 define menu on page component instead of root component

I am having trouble trying to implement a simple menu in my Ionic 2 project. All of the examples I have seen online define the HTML for the menu within app.html and then only have a button with the menuToggle tag on the page that uses the menu.

Here's what I am trying to do. The root page of the app is a login page of sorts, called HomePage. this page is defined as rootPage in app.ts as seen below. After the user logs in, they are brought to the SettlementPage page. On this page, the user should be able to open a menu that displays a list of other settlements the user can travel to.

My problem is that I need to define the menu and its content from within the context of the SettlementPage, not the HomePage, which seems to be the way all of the examples do it. I am confused about how to go about doing this, since there is not much documentation on the topic. Specifically, I am confused about how the line <ion-nav #mycontent [root]="rootPage"></ion-nav> operates. What exactly does this bind the menu to? In all of the examples, rootPage is a member of the root component defined in app.ts. How would I go about binding a menu to a specific Page component?

One line of thinking I went down was that I needed to bind the menu to the ion-content section of this particular page's HTML. So, I added an ID field as in <ion-content id="content"> and then tried to reference it with <ion-menu [content]="content"> but that didn't seem to work. I also tried setting this.rootPage = this; within settlement-page.ts but that didn't work either.

I think I have some sort of fundamental misunderstanding about how menus are supposed to be bound to Pages. Is it even possible to do this, or does a menu have to be defined on the root component and accessed elsewhere referring to some sort of ID?

Here is the relevant code from my project for reference:

app.ts:

import {App, Platform} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
import {HomePage} from './pages/home/home';

@App({
  template: '<ion-nav [root]="rootPage"></ion-nav>',
  config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
export class MyApp {
  rootPage: any = HomePage;
  platform: Platform;

  constructor(platform: Platform) {
    this.platform = platform;
    this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
    });
  }
}

settlement-page.html:

<ion-navbar *navbar>
  <button menuToggle side="left">
    <ion-icon name="menu"></ion-icon>
  </button>
  <ion-title>
    {{settlement.name}}
  </ion-title>
</ion-navbar>

<ion-menu side="left" [content]="mycontent">
  <ion-toolbar>
    <ion-title>Settlements</ion-title>
  </ion-toolbar>

  <ion-content>
    <ion-list>
      <button ion-item *ngFor="let settlement of settlements" 
                       (click)="travelTo(settlement)">
          {{settlement.name}}
      </button>
    </ion-list>
  </ion-content>
</ion-menu>

<ion-content>
  <p>Name: {{player.name}}</p>
  <p>Caps: {{player.caps}}</p>
</ion-content>

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

settlement-page.ts:

import {Page, NavController, NavParams, MenuController} from 'ionic-angular';
import {Player} from '../../providers/classes/player';
import {Settlement} from '../../providers/classes/settlement';
import {SettlementService} from '../../providers/services/settlement-service';
import {SqlService} from '../../providers/services/sql-storage-service';

@Page({
    templateUrl: 'build/pages/settlement-page/settlement-page.html',
    providers: [SqlService, SettlementService]
})
export class SettlementPage {
  private nav: NavController;
  private navParams: NavParams;
  private sqlService: SqlService;
  private settlementService: SettlementService;
  private player: Player;
  private settlement: Settlement;
  private settlements: Settlement[];
  private menu: MenuController;

  constructor(nav: NavController, navParams: NavParams, 
              sqlService: SqlService, settlementService: SettlementService,
              menu: MenuController) {
    this.nav = nav;
    this.navParams = navParams;
    this.sqlService = sqlService;
    this.settlementService = settlementService;
    this.menu = menu;

    this.player = navParams.get('player');
    this.settlement = navParams.get('settlement');
    this.settlements = settlementService.getSettlements();
    //don't allow navigation to current settlement
    this.settlements.filter((value: Settlement) => value != this.settlement);
    console.log(this.menu.getMenus());
  }
}

On the final line, this.menu.getMenus() returns an empty array, which tells me that the menu I have defined in settlement-page.html is not being recognized. I'm not sure what I'm doing wrong here.

Currently, the menu icon appears in the top left corner of the nav bar, but when I click on it a blank, transparent menu slides out from the left.

Any advice would be much appreciated. I've been stuck on this for a few hours now and there seems to be nothing online about defining and using menus outside of the app's root component.

like image 416
Pete MacLellan Avatar asked May 31 '16 21:05

Pete MacLellan


1 Answers

I followed the answer of Manu Valdés stated above but had to change a bit for ionic 2. What I did was:

Add to the page where menu is not necessary:

import { MenuController } from 'ionic-angular';

constructor(public menu:MenuController) {
 ionViewDidLoad() {
    this.menu.enable(false);
  }
  ionViewDidLeave(){
    this.menu.enable(true);
  }
}
like image 80
Jannat Tumpa Avatar answered Sep 24 '22 16:09

Jannat Tumpa