0

I'm updating an existing ionic/angular app and would like to have as little impact on the code as possible. My goal is to add a burger menu, as exists in a ton of other applications. My difficulty comes from the project architecture.

The header is created in a distinct component, nav-bar. It manages different states and context. Each page, modal, etc... sets up his own ion-header tag, but then its content (and mainly the ion-toolbar) is managed in the dedicated navbar component.

Here is a lightened working version of the code :

app.component.html

<ion-app>
    <ion-menu content-id="main-content">
        <ion-header>
            <ion-toolbar>
                <ion-title>Menu Content</ion-title>
            </ion-toolbar>
        </ion-header>
        <ion-content class="ion-padding">This is the menu content.</ion-content>
    </ion-menu>

    <ion-router-outlet *ngIf="isLoggedIn" id="main-content"></ion-router-outlet>
</ion-app>

about.page.html

<ion-header>
    <nav-bar [title]="'title.about'"></nav-bar>
</ion-header>

<ion-content padding>
    <!-- custom page content -->
</ion-content>

navbar.html

<ion-toolbar>
    <ion-buttons slot="start">
        <ion-button *ngIf="!isModal" (click)="goToPrevious()">
            <ion-icon name="chevron-back"></ion-icon>
        </ion-button>
        <ion-menu-button></ion-menu-button>
    </ion-buttons>

    <ion-title class="title-wrapper" slot="primary">{{ title }}</ion-title>
</ion-toolbar>

The navbar works (as in the title is displayed correctly as the back-button), except the burger button: it is not showing on a the page. In the developer console, I can see the element being added to the page, but not visually. It "magically" appears if I add a "display: block" on it, which clearly doesn't feel right.

What did I miss, why is the button not showing by itself?

Michael Maurel
  • 87
  • 2
  • 15

1 Answers1

0

The solution was heavily inspired from a post by Alon Laniado Bundayy Olayinka on this thread

  • First of all, I disregarded using a ion-menu, I finally preferred to make my own.
  • Secondly, the balise had to be moved alongside the rest in my new component. There was no logic to have the balise on each page, then the content outside
  • Finally, it was easier, cleaner and sturdier to make this new component in a module to facilitate the injection anywhere else.

Here are my different files for anyone stumbling upon here.

app/modules/shared/shared.module.ts

    import { CommonModule } from '@angular/common';
    import { NgModule } from '@angular/core';
    import { IonicModule } from "@ionic/angular";
    
    import { NavBar } from "./nav/nav";
    
    @NgModule({
        declarations: [NavBar],
        imports: [
            CommonModule,
            IonicModule,
        ],
        exports: [NavBar],
    })
    export class SharedModule { }

app/modules/shared/navbar/nav.ts

    import { Location } from '@angular/common';
    import { Component, Input, OnInit } from '@angular/core';
    import { NavController } from '@ionic/angular';
    
    @Component({
        selector: 'navbar',
        templateUrl: 'navbar.html',
        styleUrls: ['nav.scss'],
    })
    export class NavBar implements OnInit {
        @Input() public title = '';
    
        constructor(
            public location: Location,
            public navCtrl: NavController
        ) { }
    }

app/modules/shared/nav/nav.html

<header>
    <nav>
        <div class="navbar__container">
            <div class="navbar__left">
                <!-- Navigation button -->
                <button aria-label="navigation-button">
                    <img src="assets/imgs/menu/menu-back.svg">
                </button>
                <!-- Burger menu -->
                <button aria-label="menu-button">
                  <img [src]="toggleBurgerMenu? 'assets/imgs/menu/burger-close.svg' : 'assets/imgs/menu/burger-open.svg'">
                </button>
            </div>
            <div class="navbar__right">
                <!-- Page title-->
                <span class="text text__size--regular text--primary">{{ title }}</span>
            </div>
        </div>
    </nav>
</header>

Then, this SharedModule is added in the imports array of the app.module.ts, and added as such on the specific component supposed to use it:

<navbar [title]="custom-title"></navbar>

Note that this import and usage is to be duplicated for each subsequent module or page.

Michael Maurel
  • 87
  • 2
  • 15