はじめに
今回プロジェクトで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つのタブがある画面が作成されます。
各ページのヘッダー部分が共通しているので、この部分をコンポーネントとして切り出し、コンポーネントの呼び出しを行う作りに変更していきます。
コンポーネントの作成
まずは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つのコンポーネントが構成されています。
各ヘッダー部分のデフォルトの作りはこうなっています。
<ion-header><ion-toolbar><ion-title>
Tab One
</ion-title></ion-toolbar></ion-header>
これを生成したヘッダーのhtmlファイルにコピペします。
ヘッダータイトル表示部分は親コンポーネントからのデータをバインドするため、テンプレート式に書き換えます。
さらに戻るボタンを加え、ページごとにボタンを出し分けるため*ngIf
を記載します。
<ion-header><ion-toolbar><ion-buttons*ngIf="showBackButton"slot="start"><ion-back-buttondefaultHref="/"></ion-back-button></ion-buttons><ion-title>
{{headerTitle}}
</ion-title></ion-toolbar></ion-header>
次にtsファイルでテンプレートを作成した部分のプロパティを記述します。@Input()
デコレーターを付けることで親から子へと値が連携されるようになります。
import{Component,OnInit,Input}from'@angular/core';@Component({selector:'app-header',templateUrl:'./header.component.html',styleUrls:['./header.component.scss'],})exportclassHeaderComponentimplementsOnInit{constructor(){}@Input()headerTitle:String;@Input()showBackButton:Boolean;ngOnInit(){}}
これで子コンポーネント側の準備は完了です、次に呼び出す側のtab1
を手直ししていきます。
親ページからの呼び出し
使用するコンポーネントのselector名をタグにして記載します。今回はheader.component.ts
を見てselector
を確認します。使用するコンポーネントのプロパティが属性となっているのでタイトルに表示する文字列と、戻るボタンの表示の真偽値を設定します。
<app-headerheaderTitle="Parent Tab One"showBackButton=true></app-header><ion-content> ・・・
ヘッダーコンポーネントをインポートして、declarations
に追記します。
使うモジュールはdeclarations
に記述する必要があります。
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]})exportclassTab1PageModule{}
ヘッダー部分が親が指定した文字列が連携できていることが確認できます。
他のページでもヘッダー部分をコンポーネントの呼び出しに書き換えれば、各ページで作っていたヘッダー部分のコンポーネント化が完了です。
おわり
Angularは他のフレームワークと比べ学習コストが高いと言われていますが、こういう基本的なところではまだ学習コスト高いと感じません。
やっぱりDI(依存性の注入)とかかとっつきづらい感じなんでしょうか。