In Ionic 1, we have the ability to define an <ion-nav-bar>
above an <ion-nav-view>
, which serves as a generic nav bar for the entire app and we could turn it off on a per-view basis (using ionNavView
's hideNavBar=true|false
.
It appears in Ionic 2 we have to insert an <ion-nav-bar>
per page - and cannot have a global nav bar for the entire app. Is that correct, or am I missing a trick?
If so - it seems like a lot of duplicated code?
Also, it appears you do not have the ability for the NavBar to build its own back button, and you have to write the own mark-up for the back button yourself (per page) which, again, seems like a lot of code duplicate.
UPDATE:
Just like @mhartington says:
There is no way to create a global ion-navbar, as this is done on purpose. The point of having a navbar defined for each component is so that we can properly animate the titles, navbar background color (if you change them) and animate other properties needed.
And about creating a custom directive to avoid duplicating ion-navbar
html code:
That will still creat errors with how angular2 content projection works. We have several issues that have been open when people try this and the best answer is to not do it.
NOT recommended solution:
In order to avoid duplicating so much code, you can create your own custom component for the navbar.
Create a navbar.html
with this code:
<ion-navbar *navbar>
<ion-title>MyApp</ion-title>
<button menuToggle="right" end>
<ion-icon name="menu"></ion-icon>
</button>
<ion-buttons *ngIf="!hideCreateButton" end>
<button (click)="createNew()"><ion-icon name="add"></ion-icon></button>
</ion-buttons>
</ion-navbar>
And then in the navbar.ts
:
import {Component, Input} from '@angular/core';
import {NavController} from 'ionic-angular';
import {CreateNewPage} from '../../pages/create-new/create-new';
@Component({
selector: 'navbar',
templateUrl: 'build/components/navbar/navbar.html',
inputs: ['hideCreateButton']
})
export class CustomNavbar {
public hideCreateButton: string;
constructor(private nav: NavController) {
}
createNew(): void {
this.nav.setRoot(CreateNewPage, {}, { animate: true, direction: 'forward' });
}
}
By declaring the hideCreateButton
as an input
of the Component
, you can decide in which pages show that button and in which ones should not be visible. So in this way, you can send information to tell the component how it should be, and customize it for each page.
So if you want to add the navbar in a page (without modifying the default template, so showing the create button) you just have to add the navbar
element (binded to our custom component by us in the selector
property):
<navbar></navbar>
<ion-content>
...
</ion-content>
And if you want to hide the create button (or modify you navbar like you want to) your page will look like this one:
<navbar [hideCreateButton]="hidebutton()"></navbar>
<ion-content>
...
</ion-content>
And remember that the hideButton()
should be defined in your customPage.ts
like this:
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl } from '@angular/common';
@Component({
templateUrl: 'build/pages/create-new/create-new.html',
directives: [FORM_DIRECTIVES]
})
export class CreateNewPage{
private hideCreateButton: boolean = true;
public hidebutton(): boolean {
return this.hideCreateButton;
}
}
For ionic 3+
What I did to solve this was simply use a custom component.
ionic generate component navbar
Then in any of your page templates, simply use it as a custom element e.g
<navbar></navbar>
<ion-content padding>
...
</ion-content/>
I had a similar issue creating an Ionic 4+ app (@ionic/angular 4.6.2), I wanted to add a login button and some other global stuffs in the header.
You can achieve that in a quite simple way.
Just add a ion-header containing a ion-toolbar in your app.component.html as a global header, like this:
<ion-header class="page-header">
<ion-toolbar id="main-toolbar">
<ion-title>
<ion-label>{{ pageTitle }}</ion-label>
</ion-title>
<!-- add here all the things you need in your header -->
</ion-toolbar>
</ion-header>
<ion-router-outlet id="content" main></ion-router-outlet>
The problem here is that the "global header" will overlay the content of any page if you do only that. So has a workaround just add an empty ion-header containing an empty ion-toolbar on top of all your pages before the content tag, as follow:
<ion-header>
<ion-toolbar></ion-toolbar>
</ion-header>
<ion-content>
<!-- your content here -->
</ion-content>
Doing that the "global header" will overlay the page header and the content will begin just after it.
Then you can manage all the code for your global header controls in your app.component.ts file.
I guess there could be some strange behaviour if the main header has a height greater than the "standard" toolbar height but with some nice CSS you should be able to fix it.
Furthermore, this workaround works fine with a side menu.
Hope it helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With