Ionicでアプリ開発をしていると、バックボタンで画面を移動する際にそのまま前の画面に戻るのではなく、意図的に戻り先を操作したい場合があります。
例えば、ある機能を使うにはユーザー登録が必要で一度ユーザー登録画面に遷移して登録完了後に元の画面に戻り、引き続き操作を続行させる場合です。
この時、実際にはユーザー登録画面を挟んでいてもバックボタンではユーザー登録画面に戻らないようにしないと登録完了後の動作としてはおかしくなってしまいます。
また、ユーザー登録時には入力した内容を確認する画面なども表示しているので登録完了後はこの画面も表示したくはありません。
履歴を消す
一番簡単な対策は$state.goをおこなう際に
$ionicHistory.nextViewOptions({ disableBack: true, historyRoot: true });
を指定することで最初の画面としてバックボタンを禁止してしまうことです。
ところが、画面によってはメニューが存在しないため、バックボタンが消えてしまうと、どこにも移動できなくなってしまったり、操作上不便になってしまうことがあります。
不要な画面の履歴だけを消す
そこで$ionicView.enterなどで下記のように指定し、ユーザー登録や確認画面などの不要なバックビューを削除する方法を使います。
ただし、removeBackView()は同一画面上では1回しか実行できないため、複数画面の履歴を同時に削除することができません。
前の画面に戻るgoBack(-2)などとは違ってremoveBackView(-2)とやってもエラーが出てしまい、複数画面の履歴を消すことはできないのです。
そこで次画面遷移後に一画面づつ消していく方法をとります。
もちろん、何でもかんでも消してしまうと遷移がおかしくなってしまうので前の画面の名前を調べて戻ってほしくなければ消すといった工夫が必要になります。
画面の遷移情報を参照する
$ionicHistory.viewHistory()を使えば画面遷移の履歴を参照することができます。
console.log($ionicHistory.viewHistory());
全体の履歴以外にも下記のように個別に確認する方法もあります。
前の画面:console.log($ionicHistory.backView());
現在の画面:console.log($ionicHistory.currentView());
次の画面:console.log($ionicHistory.forwardView());
遷移がうまくいかない時はこれらを使って調整することができますが、あまり多用しても反映が遅かったり、console.logを入れた場所でなく、最終的な状態が出力される場合があるので鵜呑みにせず状況に応じて判断することも必要です。
履歴は編集できない
上記を使えば画面の遷移情報は参照できるものの、これを書き換えてみたらどうなるのでしょう?
$ionicHistory.backView().stateName = 'top';
※似たような項目にstateIdがありますが、こちらはstateParamsが含まれてくるので画面名としてはstateNameを参照します
これによって遷移先が変更できる場合もあるようですが、他の項目がそのままになってしまい矛盾が生じてしまうので避けた方が無難です。
また、スタックを編集して画面遷移の履歴を自由に書き換えられれ自由度が高まります。しかしこれも参照用で実際の履歴は別のところにあるようで残念ながらうまくいきませんでした。
console.log($ionicHistory.viewHistory().histories[$ionicHistory.currentHistoryId()].stack);
同じ画面が続いてしまった場合の対策
条件に応じて前の画面履歴だけを消す方法で正しく遷移するように調整しようとすると、かなりややこしくなってしまいます。
removeBackView()で不要な画面を消したつもりでもバックボタンを押してみると同じ画面が続いてしまうことがありますので、その場合は前画面のstateNameを調べて同じだったらgoBack()を使うなどといった工夫も必要です。
$state.goで元の画面に遷移した時はバック扱いにしてくれます。ところが、間に入った遷移を消して同じ画面が続いてしまっても勝手には直してくれません。
このようにどうしてもうまくいかなくてバグかと疑いたくなることがあっても、結果的には自分の勘違いだったということが多いです。
$ionicHistoryは独特のクセがあるので、画面遷移の調整は大変かもしれませんが、きちんと追っかけていけば思い通りにすることも不可能ではありません。