LoginSignup
13
13

More than 3 years have passed since last update.

Ionic4での画面遷移の種類と使い分け

Last updated at Posted at 2019-12-08

Ionicには画面遷移を実現する方法が複数用意されていて、Ionic3と4で似ている部分や変わった部分もあります。自分の場合、仕事の都合でIonic3に慣れ始めてからIonic4へ乗り換えたため、違いや使い分けが分からず実装に一貫性がなくなってしまうこともありました。(作り直したい……。)

この記事では、Ionic4の画面遷移まわりの機能の種類や、どういった意図でそれらを使い分けると良いのか、現時点での考えを記載します。

ion-router-outletNavController

Angular版のIonicで推奨されている画面遷移の機能です。

Angular Routingと統合されており、URLベースの画面遷移を提供します。使い方はAngularのrouter-outletとほぼ同じですが、Ionic独自の拡張がされています。

HTML側からはa要素のrouterLink属性、TypeScript側からはNavControllerクラスを使って遷移を制御します。

このNavControllerはIonic3のNavControllerとは別物で、メソッド名や引数も変わっています。

ナビゲーションスタック

ion-router-outletでの画面遷移にはIonic独自のナビゲーションスタックの概念があります。この概念はIonic3と4でほぼ変わりません。

ナビゲーションスタックは画面遷移の履歴をキャッシュする仕組みのようなもので、ナビゲーションスタックに追加された画面は次の画面に遷移してもコンポーネントのインスタンスが維持されます。この挙動は通常のAngularとは違うので注意が必要です。

次の画面へ進む機能・使い分け

  • NavConrtrollernavigateForward()で遷移する場合、ナビゲーションスタックに現在までの画面を残したまま次の画面コンポーネントを表示します。デフォルトでは次へ遷移するアニメーションが発生します。
    • routerLinkrouterDirectionを指定しない、又はrouterDirection="forward"を指定した場合も同じ挙動になります。
  • NavConrtrollernavigateRoot()で遷移する場合、これまでのナビゲーションスタックを破棄して、次の画面から新規のナビゲーションスタックを開始します。デフォルトではアニメーションは発生しません。
    • routerLinkrouterDirection="root"を指定した場合も同じ挙動になります。

使い分けは、

  • 一般的な画面遷移ではnavigateFoward()
  • ナビゲーションスタックをリセットしたい場合はnavigateRoot()

となります。一般的なnavigateForward()は、次の画面に進んでもコンポーネントのインスタンスが残り続けることを必ず意識しましょう。

前の画面へ戻る機能・使い分け

前へ戻るためのメソッドでは、微妙に機能が違うものが複数提供されています。全てのメソッドで、デフォルトでは前へ遷移するアニメーションが発生します。

  • NavControllerpop()で遷移する場合は、ナビゲーションスタックの直前の画面へ戻り、今見えている画面はナビゲーションスタックから破棄されます。
  • NavConrtrollernavigateBack()で遷移する場合は、引数で指定された画面がナビゲーションスタックに含まれている場合、それよりも後のナビゲーションスタックは破棄されます。
    • routerLinkrouterDirection="back"を指定した場合も同じ挙動になります。
  • NavControllerback()で遷移する場合は、AngularのLocation.back()と同じ挙動になります。

使い分けとしては以下のようになります。

  • コンテクストに応じて前の画面に戻したい場合はpop()
  • コンテクストに関係なく特定の画面に戻したい場合はnavigateBack()
  • ブラウザのバックボタンと同じ挙動で前に戻したい場合はback()

パラメータの渡し方

Angular Routerと同じ方法で遷移先の画面へパラメータを渡せます。
https://angular.jp/guide/router

ion-modalModalController

ion-modalは、見えている画面の上に別のコンポーネントを重ねて表示する機能で、ion-modalの生成・表示・非表示を制御するのがModalControllerです。

特にスマートフォンサイズの場合、MaterialDesignテーマではion-router-outletによる遷移と見た目としてはほぼ同じ効果が起こります。しかし、ルーティングによる画面遷移と意味合いは異なります。

ルーティングによる画面遷移との違い・使い分け

ion-router-outletを使ったルーティングによる画面遷移ではURLが変化します。また、遷移中のアニメーションが終了した後は、遷移前後の画面を同時に表示することが想定されていません。

一方ion-modalでコンポーネントを表示する場合は、既存の画面表示とURLを維持したまま、単純にその上へ新しいコンポーネントを重ねて表示します。表示の制御もルーティングとは独立しており、またion-modal単体で複数のコンポーネントを切り替えて表示する機能はありません。

そのため、ion-router-outletとの使い分けは次のようになります。

  • ion-modalを使う場合
    • コンポーネントを重ねて同時に表示したい
    • ルーティングへ影響を与えず、一次的に別の画面を表示したい
  • それ以外はion-router-outletを使う

パラメータの渡し方

parent.component.ts
...
public async createModal(): void {
  const modal = await this.modalCtrl.create({
    component: ChildComponent,
    componentProps: { id: this.id }, // *A
  });
  await modal.present();
  const { data } = await modal.onDidDismiss(); // *b
  console.log(data.result);
}
child.component.ts
@Component({...})
export class ChildComponent {
  @Input() public id: string; // *a
  constructor(
    private modalCtrl: ModalController
  ) {
  }

  public close(): void {
    this.modalCtrl.dismiss({ result: 'success' }); // *B
  }
}

モーダルの生成元からモーダル内部へのデータの引き渡し

componentPropsというキーでオブジェクトを渡すと、モーダル内部の同名のプロパティへ自動的に引き渡されます。(*A, *a部)

モーダル内部からモーダル生成元へのデータの引き渡し

モーダル内部からModalControllerdismiss()へ引数として渡したデータを、モーダル生成側のコンポーネントからはonDidDismiss()onWillDissmiss()で非同期で受け取れます。(*B, *b部)

ion-nav

ナビゲーションスタックを持ち、ion-router-outletと似た画面遷移の機能を提供します。しかし、ルーターとしての機能はなくルーティングには影響しません。

Ionic3のion-navNavControllerとよく似ていますが、Ionic4のAngular版であえてion-navを使うべき状況は限定的だと思われます。

ion-modalの内部で画面遷移をさせたい場合はion-navを組み合わせて使うことになります。

// ion-navの使い方についてはあとで追記したいです…。

終わりに

表面的な挙動としては似ているところもあるion-router-outletion-modalion-navですが、全て実装方法が違うので、ある実装のために作ったコンポーネントを別の実装に使いまわそうとしてもできなかったりします。

特別な要件がなければion-router-outletでの画面遷移に寄せるべきでしょう。

ドキュメントだけでは分からない部分も多いので、ググっても見つからない部分はGitHubのソースコードを読みに行くのが良さそうです。

13
13
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
13
13