Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ionic 3: One header component for several pages

I'm migrating from AngularJS to Angular and started to use Ionic 3 (latest) to build my app.

But I have a small problem: I want to use one header on some pages with sign out function and etc. I don't want to implement it in every component page and I want to avoid duplication of code.

I tried on my own. First of all I create separate header component


header.html

<ion-header>
  <ion-navbar color="primary-light">
    <ion-title>
        Super App
    </ion-title>
    <ion-buttons end>
        <button ion-button class="button-out" icon-only (click)="signOut()">
            <ion-icon class="fa fa-sign-out"></ion-icon>
        </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

header.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'app-header',
  templateUrl: './header.html'
})
export class HeaderComponent {

    constructor(public navCtrl: NavController) {}

    signOut() {
        //some auth strategy and then
        this.navCtrl.popToRoot();
    }
}

The I go to pages where I want to add my header, I made import {HeaderComponent} from './../header/header' in page.module.ts, add HeaderComponent to declarations and entryComponents and added to page.html <app-header></app-header> and it was appeared. But when I made the same into another page - I had an error:

Failed to navigate: Type HeaderComponent is part of the declarations of 2 modules: PageOneModule and PageTwoModule! Please consider moving HeaderComponent to a higher module that imports DeliveryPageModule and PageTwoModule. You can also create a new NgModule that exports and includes HeaderComponent then import that NgModule in PageOneModule and PageTwoModule.

Then I went to app.module.ts and import header there (before I removed header from page1 and page2 modules) and I've got follow error:

Template parse errors: 'app-header' is not a known element: 1. If 'app-header' is an Angular component, then verify that it is part of this module. 2. If 'app-header' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]

I looked for examples but they are didn't work in Ionic 3. Can anybody to help with it or give a working manual how to do it?

like image 272
Merge-pony Avatar asked Apr 28 '17 08:04

Merge-pony


1 Answers

As suggested by the error message, you want to create a shared NgModule that both declares and exports your shared header component. For example:

shared.module.ts

import {NgModule} from '@angular/core';
import {IonicPageModule} from 'ionic-angular';
import {HeaderComponent} from './header-component';

@NgModule({
  imports: [IonicPageModule.forChild(HeaderComponent)],
  declarations: [HeaderComponent],
  exports: [HeaderComponent]
}) export class SharedModule {}

Then you need to import that NgModule in all of the modules that use it.

Consuming code will have the form

page-one.module.ts

import {NgModule} from '@angular/core';
import {IonicPageModule} from 'ionic-angular';
import {SharedModule} from './shared.module';

@NgModule({
  imports: [IonicPageModule, SharedModule]      
}) export class PageOneModule {}

page-two.module.ts

import {NgModule} from '@angular/core';
import {IonicPageModule} from 'ionic-angular';
import {SharedModule} from './shared.module';

@NgModule({
  imports: [IonicPageModule, SharedModule]      
}) export class PageTwoModule {}

If you want to know why Angular punishes you for correctly following your instincts to reduce duplication by creating shared constructs, that is anyone's guess.

like image 115
Aluan Haddad Avatar answered Sep 21 '22 08:09

Aluan Haddad