Ionic Advent Calendar 2019
5日目の記事です。
もともとAngular で開発経験のあった私が、ionicも似たようなもんやろ!と思ってろくにドキュメントも読まずに開発していてハマった、ページのスタックについて書きます。
Ionicは一度表示したページをスタックしている
Ionic では、Angular の<router-outlet />
を継承・拡張した<ion-router-outlet />
というrouter outletが使われています。これによってAngularのナビゲーションとは異なり、ナビゲーションした後も、ナビゲーションする前のページをDOMに残すスタック方式のルーティングになっています。
以前特定のページにHostlistener でkeydown event を登録していたところ、そのページを表示して以降ずっとそのkeydown event が有効になってしまったことがありました。これはページをスタックしていたために起こっていたようです。
スタックされると何が変わる?
この記事のタイトルにもあるように、コンポーネントが破棄されないので、AngularのライフサイクルメソッドであるngOnInit
は最初に呼ばれたときだけ、ngOnDestory
はスタックから破棄されるときだけ呼ばれます。
なのでAngularでよくやる、ngOnInit
でObservableをsubscribeしてngOnDestory
でunsubscribeするみたいなコードを書くと、一度表示されたらそれ以降スタックから破棄されるまでsubscribeし続けてしまいます。
スタックを消したいとき
ユーザーがログアウトした後など、今までのスタックを全部消して新しく始めたい場合は、下記2つの方法で実現できます。
- template側:
routerLink
のプロパティrouterDirection="root"
を併記する - ts側: ionic-angular の
NavController.navigateRoot()
を使う
Hostlistener はどうすればよかったか
Hostlistenerでイベントを登録するとコンポーネントが破棄されない限り登録を解除できないので、コンポーネントにisDisplay
みたいなプロパティを持ってIonicのライフサイクルメソッドで更新、HostlistenerにisDisplay
のガード節を追加すればよかったと感じています。
まとめ: 素直にIonicのライフサイクルメソッドを使おう
色々試してみたところIonicのスタックは、IonicがよしなにPushしたりPopしたりしてくれる様でOnInitやOnDestoryがいつ呼ばれているかイマイチ分かりづらいので、OnInitやOnDestoryは使わずにIonicのライフサイクルメソッドを使った方が良さそうです。
もともとAngularを使っている人がIonicを使ったときのつまづきポイントである、ページのスタックについてでした!