ionic

Ionic初心者向け入門

はじめに

この記事は、最近フロントエンドでIonicを触る案件に参画したので、
簡単なTODOアプリを作成するために、大事そうなことをメモしたものをまとめたものです。

TODOアプリのリポジトリ

https://github.com/yuta-ushijima/ionic-tutorial

デフォルトで表示するページを指定する

「selectedIndex=""」を使うと、指定したIndexがデフォルトページとして設定できる。
Index指定なので、0が一番最初のページ。

devサーバーを動かす

$ cd プロジェクトディレクトリ
$ ionic serve

ionicのプロジェクトを作成する

ionic start プロジェクト名 テンプレート名

componentの追加

pageディレクトリ配下に、作成したいコンポーネントのディレクトリを作る

mkdir -p page/component_name

app.module.tsにコンポーネントを登録する

※Ionicでは、フォルダ内にファイルを置くだけでは、使用できないので、
@NgModuleに追記する必要がある

import { HomePage } from '../pages/home/home'; // コンポーネントのインポート
import { LoginPage } from '../pages/login/login'; // コンポーネントのインポート

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    LoginPage //ここにコンポーネントを追記する
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    LoginPage //ここにコンポーネントを追記する
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

コンポーネントをgenerateする

$ ionic g <component_name> <option>

オプション

--no-module #モジュールが作られない

参考サイト

https://ionicframework.com/docs/cli/generate/

Ionicで指定できるテンプレート

便利コマンド

ionic docs

リファレンスをターミナルから起動可能。

ionic info

プロジェクトの内部情報を出力する。

Yutas-MacBook-Air:ionic_tutorial ushijimayuuta$ ionic info
✔ Gathering environment info - done!

Ionic:

   ionic (Ionic CLI)  : 4.1.1 (/usr/local/lib/node_modules/ionic)
   Ionic Framework    : ionic-angular 3.9.2
   @ionic/app-scripts : 3.2.0

Cordova:

   cordova (Cordova CLI) : not installed
   Cordova Platforms     : not available
   Cordova Plugins       : not available

System:

   NodeJS : v8.9.4 (/usr/local/bin/node)
   npm    : 6.2.0
   OS     : macOS High Sierra

hoge.module.tsの正体

このモジュールファイルは、遅延読み込み(Lazy Loading(以下LL))を実現するために存在している。

Ionicはindex.html一つで全てのTSファイルを操作するので、LLしないとTypeScriptをJavaScriptをコンパイルする際に
ロードにすごく時間がかかり、UXが悪くなる。

hoge.module.tsを用意することで、実行が必要なときに読み込ませることができる。

ただし、LLを機能させるためには、二つの条件が必須
* @componentの上に@IonicPageを記述すること
* hoge.module.tsのような、@Componentのファイル名にmoduleをつけたモジュールファイルを用意すること

なお、IonicではLLするページは文字列として表記する必要がある。
ただし、importやapp.module.tsへの追加は不要。

{ title: 'タスク一覧', component: 'TaskListPage' }

Ionicのオリジナルタグについて

アプリ表示タグ

<ion-app></ion-app>

#contentでion-navにcontentというネーミングをしている(要素参照のため)
swipeBackEnabled...スワイプを無効化
[root]...中身に何を表示するか決めるプロパティ(ここではrootPageを指定)
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>

サイドバーの表示

[content]プロパティにcontentを指定することで、メニューが表示されている間は、

contentがついているを右に押し出して表示する。

TypeScriptについて

pagesの型宣言(TypeScript)

title => string型
component => any型

pages: Array<{title: string, component: any}>;

this.pagesになっているのは、pagesがメソッドとして括られているため
これにより、サイドバーをデータバインディングしている

this.pages = [
  { title: 'Hello Ionic', component: HelloIonicPage },
  { title: 'My First List', component: ListPage }
];

メソッドの定義(ここでは、(click)で発火させるためのメソッドを定義している)

openPage(page) {
  // close the menu when clicking a link from the menu
  this.menu.close();
  // navigate to the new page if it is not the current page
  this.nav.setRoot(page.component);
}

Angularについて

*ngFor...繰り返しを指示する構文(*ngFor="let <変数> of <展開する配列>")
let p of pages...配列のpagesからpという名前で順番に値を取り出す
(click)...onClickと同じ意味。ユーザーがクリックすると、指定したメソッド(ここではopenPage(p))が実行される。
(click)で発火するメソッドは、app.components.tsなどの各component.tsで定義する

<button ion-item *ngFor="let p of pages" (click)="openPage(p)">
  <!--pの中のtitleを取り出す-->
  {{p.title}}
</button>

配列の作り方

export class HelloIonicPage {
  // string型のtitle変数を定義し、デフォルトの値を代入する
  title: string = 'タスク登録';
  // 配列tasksを用意し、オブジェクトにstring型のnameを格納
  //  nameをキーとしたオブジェクトの型が{ name: string } でそれを配列[]で格納
  // 配列[]はArray<>でも表記可能
  tasks: { name: string }[] = [
    { name: 'タスク1' },
    { name: 'タスク2' },
  ];
  constructor() {

  }
}

双方向でデータバインディングを行う

テンプレート側

[(ngModel)]="task" name="task"

TSファイル側

task: string;

バリデーションのやり方

  1. formタグの中で#f="ngFormとすることで、ローカル変数を定義する
  2. requiredminlength/maxlengthなどを使ってバリデーションを定義
  3. submitの箇所で[disabled]="!if.form.valid"とすれば、条件に満たしてない場合にボタンがdisabledになる。
<ion-content padding>
  <!--submitイベントが発生したときにaddTask()メソッドを呼び出す-->
  <!--#f=ngFormによってHTMLテンプレート内で使うローカル変数の定義を行う-->
  <form padding (submit)="addTask()" #f="ngForm">
    <ion-list>
      <ion-item>
        <ion-label floating>タスク</ion-label>
        <ion-input type="text" [(ngModel)]="task" name="task"
                    required minlength="3" maxlength="20"></ion-input>
      </ion-item>
    </ion-list>
    <button type="submit" ion-button block [disabled]="!f.form.valid">追加</button>
  </form>

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