Igor
Igor

Reputation: 673

How to create a reusable component with Ionic 3 and Angular 4

I want to create a reusable header to my app. So, I did:

Created the component (app-header):

app-header.ts:

import { Component } from '@angular/core';

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

  text: string;

  constructor() {
    console.log('Hello AppHeaderComponent Component');
    this.text = 'Hello World';
  }

}

That have the HTML:

app-header.html:

<div>
  {{text}}
</div>

And I've added the AppHeaderComponent to declarations in @NgModule:

...

import { AppHeaderComponent } from '../components/app-header/app-header';

@NgModule({
  declarations: [
    MyApp,
    TabsPage,
    AppHeaderComponent
  ],

...

I'm using TabsTemplate and I want to add this component in every tab, so, I did on feed.html (one of my tabs):

<app-header></app-header>

<ion-content>

...

But it gives tthe following error:

Uncaught 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 ->]

So, I changed app-header.ts to:

import { Component, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: 'app-header.html'
})
@NgModule({
  schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})
export class AppHeaderComponent {

  text: string;

  constructor() {
    console.log('Hello AppHeaderComponent Component');
    this.text = 'Hello World';
  }

}

But the same error still here.

How can I do this?

Update:

I'm using Tabs, so, I have:

tabs.ts:

import { Component } from '@angular/core';

import { FeedPage } from '../feed/feed';
import { AboutPage } from '../about/about';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {

  tabFeed = FeedPage;
  tabAbout= AboutPage;

  constructor() {

  }
}

And tabs.html:

<ion-tabs>
  <ion-tab [root]="tabFeed" tabIcon="paper"></ion-tab>
  <ion-tab [root]="tabAbout" tabIcon="search"></ion-tab>
</ion-tabs>

And each tab load a page, like feed.html (quoted in the question)

Code architecture:

enter image description here

And components.modules.ts have:

import { NgModule } from '@angular/core';
import { AppHeaderComponent } from './app-header/app-header';
@NgModule({
    declarations: [AppHeaderComponent],
    imports: [],
    exports: [AppHeaderComponent]
})
export class ComponentsModule {}

Upvotes: 7

Views: 7095

Answers (2)

Junaid
Junaid

Reputation: 4924

This is how ComponentsModule should look like otherwise, you won't be able to use ionic wrappers like ion-grid, ion-row etc.

components.module.ts

import {NgModule} from '@angular/core';
import {CreatePostComponent} from './create-post/create-post';
import {IonicModule} from "ionic-angular";

@NgModule({
    declarations: [
    CreatePostComponent,
  ],
    imports: [
    IonicModule, <== make sure to import IonicModule
  ],
    exports: [
    CreatePostComponent,
  ]
})
export class ComponentsModule {}

and then after this, you would wanna put ComponentsModule inside imports array of any other component's module.ts file where you want to use it. Here, for example, I want to use CreatePostComponent inside my newsfeed page (ionic page).

newsfeed.module.ts

@NgModule({
  declarations: [
    NewsfeedPage,
  ],
  imports: [
    IonicPageModule.forChild(NewsfeedPage),
    ComponentsModule
  ],
})

and voila, you can then use your CreatePostComponent selector (create-post in my case) inside newsfeed.html.

<create-post></create-post>

Upvotes: 2

Sampath
Sampath

Reputation: 65988

You need to remove it from app.module.ts since it has been declared in the ComponentsModule.

app.module.ts

@NgModule({
  declarations: [
    MyApp,
    TabsPage,
    //AppHeaderComponent <-- need to remove this
  ],

After that, you need to import the ComponentsModule as shown below on the page's module where you need it.

my.module.ts

@NgModule({
  declarations: [
    MyPage,
  ],
  imports: [
    IonicPageModule.forChild(MyPage),
    ComponentsModule <-- here you need
  ],
})
export class MyPageModule { }

Upvotes: 9

Related Questions