Blog

ブログ

IonicPageを使ってみる

2018.04.13 公開
Yuko Hashimoto
Yuko Hashimoto デザイナー

先日、Ionicのプロジェクトで「この書き方は何だろう?」と引っかかり、プログラマに質問して「そんな機能が……!」と今更知ったので覚え書きです。

画面遷移の書き方が違う?

this.navCtrl.push(MyPage); // テンプレートとかで見たことある書き方 this.navCtrl.push('MyPage'); // 何だろうこの書き方・・・

プログラマからのお言葉↓

コンポーネント毎にモジュールファイルを作っているんで文字列としてコンポーネントのクラス名を指定していれば画面遷移が出来ます。
モジュールファイルを各コンポーネントで持っていると初期時に読み込みが少なくて済むんで、早く表示できると言ったメリットがあります。
Ionic3からはコンポーネントをコマンドラインから作ればモジュールも作られたような。。。

えっ……そうなの!?

IonicPage Module

IonicPageというものを使うそうです。
IonicPage – Ionic API Documentation – Ionic Framework
やってみましょう。

$ ionic start test sidemenu

とりあえずsidemenuテンプレートで作成します。

$ ionic g page next

nextというページを追加します。
するとnext.html、next.scss、next.tsと一緒にnext.module.tsというファイルが作られました。

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { NextPage } from './next';

@NgModule({
  declarations: [
    NextPage,
  ],
  imports: [
    IonicPageModule.forChild(NextPage),
  ],
})
export class NextPageModule {}

next.tsもテンプレートで作ったhome.tsと違う・・・

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular'; // IonicPageついてる

@IonicPage()  // IonicPage
@Component({
  selector: 'page-next',
  templateUrl: 'next.html',
})
export class NextPage {

  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad NextPage');
  }

}

それから、home.htmlにボタンを追加して遷移させてみると・・・

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

import { ListPage } from '../list/list';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController) {

  }

  gotoList() {
    this.navCtrl.push(ListPage); // テンプレートで作られたページ
  }

  gotoNext() {
    this.navCtrl.push('NextPage'); // ジェネレータで作ったページ
  }

}

で、できた〜〜〜〜

既にあるページにもIonicPageを適用させてみる

IonicPageを使っていなかったページに適用するためにやること

  1. ***.module.tsファイルを作成
  2. ***.tsにIonicPageに関連する記述を追加
  3. app.component.tsapp.module.tsからページの読み込み関係の記述を削除
  4. ページの指定を文字列に変更

つまり、

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { HomePage } from './home';

@NgModule({
  declarations: [
    HomePage,
  ],
  imports: [
    IonicPageModule.forChild(HomePage),
  ],
})
export class NextPageModule {}

こうして、

import { Component } from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular'; // IonicPage追加

//import { ListPage } from '../list/list'; 消す

@IonicPage() // IonicPage追加
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController) {

  }

  gotoList() {
    this.navCtrl.push('ListPage'); // 文字列に
  }

・・・

}

こうして、

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

// import { HomePage } from '../pages/home/home'; 消す
// import { ListPage } from '../pages/list/list'; 

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  rootPage: any = 'HomePage'; // 文字列に

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

  constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen) {
    this.initializeApp();

    // used for an example of ngFor and navigation
    this.pages = [
      { title: 'Home', component: 'HomePage' },  // 文字列に
      { title: 'List', component: 'ListPage' }
    ];

  }
  ・・・
}

こうして、

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';

import { MyApp } from './app.component';
// import { HomePage } from '../pages/home/home';
// import { ListPage } from '../pages/list/list';

import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

@NgModule({
  declarations: [
    MyApp,
    // HomePage,
    // ListPage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    // HomePage,
    // ListPage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

こう。

ついでにこういう設定もできます。

@IonicPage({
  name: 'my-page', // 自分を意味する文字列を変更する
  segment: 'some-path' //パスを指定する
})

この書き方だと、this.navCtrl.push('my-page');localhost:8100/#/some-pathにジャンプします。
パスの#を取りたいときはapp.module.tsIonicModule.forRoot(MyApp,{locationStrategy: 'path'})と設定します
(参照:Config – Ionic API Documentation – Ionic Framework

参考サイト

IonicPage採用時のHTMLタグ拡張(Custom Components)実装について (1/2) – Qiita
【ionic2】ionicPageで各画面をurlに対応させる – とりあえずphpとか
IonicPage – Ionic API Documentation – Ionic Framework