【Ionic3(Angular)】Componentを作成してHTMLを分割する方法まとめておく

はじめに

今回やりたかったことは以下のようなコードの「リスト」の部分が複雑になったので別ファイルに分けたいということでした。AngularのComponentを作成すれば実現できるようでIonicコマンドでComponentを作成できるのでこちらの使い方をメモしておく。

<ion-content>
  <!-- タイトル -->
  <div>Title</div>

  <!-- リスト -->
  <ion-list>
    <ion-item>Item1</ion-item>
    <ion-item>Item2</ion-item>
    ・・・
  </ion-list>

</ion-content>

やりたいことは以下
・ファイルを分割したい
・ionicのコンポーネントを使いたい
・呼びだし側と呼ばれる側とで値を共有したい

実装

Componentを作成

$ ionic g component mylist

src/componentsディレクトリが作成されてひな形が作成される

components.module.ts

import { NgModule } from '@angular/core';
import { MyListComponent } from './my-list/my-list';

@NgModule({
  declarations: [MyListComponent],
  imports: [],
  exports: [MyListComponent]
})

export class ComponentsModule {}

さらに src/components/my-list ディレクトリも作成されて html、scss、tsファイルのひな形が作成される。これをアプリから呼びだすことができるようにapp/app.module.tsに以下を追記

app.module.ts

・・・
import { ComponentsModule } from '../components/components.module' // ★追記
・・・

@NgModule({
  ・・・
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
    ComponentsModule, // ★追記
  ]
})

これで追加したmy-listコンポーネントを以下の形でよびだせるようになる。

<ion-content>
  <!-- タイトル -->
  <div>Title</div>

  <!-- リスト -->
  <my-list></my-list>

</ion-content>

Ionicコンポーネントを呼びだせるようにする

続いてmy-listコンポーネント実装していく。ionicのコンポーネント(ion-list)を使いたいのでcomponents.module.tsにIonicModuleを追記

・・・
import { IonicModule } from 'ionic-angular' // ★追記
・・・
@NgModule({
  declarations: [MyListComponent],
  imports: [IonicModule],
  exports: [MyListComponent]
})

components/my-list/my-list.html

<ion-list>
    <ion-item>Item1</ion-item>
    <ion-item>Item2</ion-item>
    ・・・
</ion-list>

呼び出し側と呼ばれる側とで値を共有する

値の共有の例として以下を実装する
・ion-listに表示する値をコンポーネントに渡す
・ion-listでクリックされた行を親に渡す

AngularのngIf、ngForを使えるようにする

追加したComponentでAngularのngIfやngForを使いたい場合はこれらも使えるようにBrowserModuleを追加する必要がある。

components/components.module.ts

import { BrowserModule } from '@angular/platform-browser';
・・・

@NgModule({
  ・・・
  imports: [BrowserModule, IonicModule],
  ・・・
})
コンポーネントに値を渡す(コンポーネントが値を受け取る)

受け取る側

components/my-list/my-list.ts

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

・・・

export class MyListComponent {

  @Input() items: any

}

component/my-list/my-list.html

<ion-list>
  <ion-item *ngFor="let item of items">{{ item.name }}</ion-item>
</ion-list>

渡す側

xxx.ts

export class Hoge {

  items: any = [
    { id: 1, name: "Item1"},
    { id: 2, name: "Item2"},
    ・・・
  ]

}

html

<ion-content>
  <!-- タイトル -->
  <div>Title</div>

  <!-- リスト -->
  <my-list [items]="items"></my-list>

</ion-content>
コンポーネントから値を受け取る

渡す側

components/my-list/my-list.ts

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

・・・

export class MyListComponent {

  @Output() selected = new EventEmitter<number>()

  ・・・

  select = (id: number) => {
    this.selected.emit(id)
  }

}

component/my-list/my-list.html

<ion-list>
  <ion-item *ngFor="let item of items" (click)="select(item.id)">{{ item.name }}</ion-item>
</ion-list>

受け取る側

xxx.ts

export class Hoge {

  select = (id) => {
    console.log(id)
  }

}

html

<ion-content>
  <!-- タイトル -->
  <div>Title</div>

  <!-- リスト -->
  <my-list (selected)="select($event)"></my-list>

</ion-content>

ずらずら書いたけど以上です。