8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Angular+Ionic4での子コンポーネントの作成とデータの受け渡し方法

Last updated at Posted at 2019-12-08

##はじめに
今回プロジェクトでIonic4というGUIフレームワークを使用することになりました。
コンポーネントの作成やデータの受け渡しというところで記述する箇所がけっこう多かったのでメモに残します。

##使用環境

  • Angular8
  • Ionic4

##前提
Ionic CLIが使用できる状態。Ionic公式やQiita記事を参考にしてください。

##プロジェクトの作成

プロジェクトを作成するディレクトリまで移動してプロジェクトを作成します。
今回はタブ付きのテンプレートプロジェクトを作成します。

ionic start myApp tabs

JSフレームワークはAngularを選択。

? Framework:
❯ Angular | https://angular.io
  React   | https://reactjs.org

雛形はtabsの他にsidemenuなどもあります。使用できる雛形は--listオプションで確認できます。

ionic start --list

##アプリの起動
作成したプロジェクトのディレクトリに移動しアプリを起動する。

cd myApp
ionic serve

ブラウザが自動起動するのでスマホサイズで確認すると、3つのタブがある画面が作成されます。
各ページのヘッダー部分が共通しているので、この部分をコンポーネントとして切り出し、コンポーネントの呼び出しを行う作りに変更していきます。

スクリーンショット 2019-12-08 14.32.57.png

##コンポーネントの作成

まずはionicのジェネレート機能使って親のページから使用する子コンポーネントを作成します。

ionic generate

コンポーネントを選択

? What would you like to generate?
  enum
  page
❯ component
  service
  module
  class
  directive

パスを指定

? Name/path of component: component/header

app下にcomponentフォルダとheaderの各種ファイルが自動生成されます。
Angularではhtml,scss,ts、あとテストファイルで1つのコンポーネントが構成されています。

各ヘッダー部分のデフォルトの作りはこうなっています。

tab1.page.html
<ion-header>
  <ion-toolbar>
    <ion-title>
      Tab One
    </ion-title>
  </ion-toolbar>
</ion-header>

これを生成したヘッダーのhtmlファイルにコピペします。
ヘッダータイトル表示部分は親コンポーネントからのデータをバインドするため、テンプレート式に書き換えます。
さらに戻るボタンを加え、ページごとにボタンを出し分けるため*ngIfを記載します。

header.component.html
<ion-header>
  <ion-toolbar>
    <ion-buttons *ngIf="showBackButton" slot="start">
      <ion-back-button defaultHref="/"></ion-back-button>
    </ion-buttons>
    <ion-title>
      {{headerTitle}}
    </ion-title>
  </ion-toolbar>
</ion-header>

次にtsファイルでテンプレートを作成した部分のプロパティを記述します。
@Input()デコレーターを付けることで親から子へと値が連携されるようになります。

header.component.ts
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
})
export class HeaderComponent implements OnInit {

  constructor() { }

  @Input() headerTitle: String;
  @Input() showBackButton: Boolean;

  ngOnInit() {}

}

これで子コンポーネント側の準備は完了です、次に呼び出す側のtab1を手直ししていきます。

##親ページからの呼び出し

使用するコンポーネントのselector名をタグにして記載します。今回はheader.component.tsを見てselectorを確認します。使用するコンポーネントのプロパティが属性となっているのでタイトルに表示する文字列と、戻るボタンの表示の真偽値を設定します。

tab1.page.html
<app-header headerTitle="Parent Tab One" showBackButton=true></app-header>
<ion-content>
 ・・・

ヘッダーコンポーネントをインポートして、declarations に追記します。
使うモジュールはdeclarations に記述する必要があります。

tab1.module.ts
import { IonicModule } from '@ionic/angular';
import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Tab1Page } from './tab1.page';
import { HeaderComponent } from '../component/header/header.component';

@NgModule({
  imports: [
    IonicModule,
    CommonModule,
    FormsModule,
    RouterModule.forChild([{ path: '', component: Tab1Page }])
  ],
  declarations: [Tab1Page, HeaderComponent]
})
export class Tab1PageModule {}

ヘッダー部分が親が指定した文字列が連携できていることが確認できます。
他のページでもヘッダー部分をコンポーネントの呼び出しに書き換えれば、各ページで作っていたヘッダー部分のコンポーネント化が完了です。

スクリーンショット 2019-12-08 14.32.13.png

####****Component is part of the declarations of 2 modulesについて
複数のコンポーネントで使用する場合にエラーが発生します。これについて記事を書きました。
Qiita -Error: Type ****Component is part of the declarations of 2 modulesの解消 -共有モジュールの作成

##おわり
Angularは他のフレームワークと比べ学習コストが高いと言われていますが、こういう基本的なところではまだ学習コスト高いと感じません。
やっぱりDI(依存性の注入)とかかとっつきづらい感じなんでしょうか。

##共に働くWebエンジニアを募集しています!
不動産SHOPナカジツでは自社サービスを作っていく仲間を募集しています。
詳しくはWantedlyからお問い合わせください。

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?