環境
- Wicket 8.0.0
背景
ページ A は検索フォームを持つ一覧画面で、一覧から個々のレコードをクリックするとページ B の詳細画面に遷移する仕様になっている。
このとき、ページ B でブラウザの戻るボタンを押すと、ページ B に遷移する前の、ページ A の検索条件や、ページネーションの表示していたページを復元するようになっている(というかそうしたい)。
問題
しかし、ブラウザの戻るボタンを押しても、検索フォームや、ページネーションなどは復元せずに、常に初期化されてしまう。
原因
結果として、原因は PageParameters の使い方にあった。PageParameters を使った画面遷移は以下のように行うと思う。
PageParameters pageParameters = new PageParameters();
pageParameters.set("id", threadData.getId());
setResponsePage(DetailPage.class, pageParameters);
しかし、今回のコードは以下のようになっていた。
PageParameters pageParameters = getPageParameters();
pageParameters.set("id", threadData.getId());
setResponsePage(DetailPage.class, pageParameters);
new PageParameters() のところが、getPageParameters() となっており、新規でページパラーメータを作るのではなく、既存のページのページパラメータを取得していた。どちらも画面遷移は正常に行われるので、正直なところ、new PageParameters() と、getPageParameters() の影響の違いについて完全に無頓着だった。まさかと思って修正してみると、そのまさかだったわけである。
補足
wicket の公式ドキュメントは以下のとおりである。
A new page version is created when a stateful page is requested for the first time or when an existing instance is modified (for example changing its component hierarchy).
意訳すると、新しいページのバージョンが生成されるのは状態を持つページを初めてリクエストしたときか、あるいは、既存のインスタンスを変更したとき(例えばコンポーネントの階層を変更したときなど)である。
要するに、getPageParameters() を呼んで、パラメータを追加したりすることは、既存のインスタンスに変更を加えたことになるようだ。この状態でページ遷移し、戻るボタンを押すと、新しいページバージョンが生成されてしまう。
画面遷移のためのページパラメータは、きちんと new しようということである。
感想
Wicket のもっとも差別化された特徴は、Stateful というところにあると思う。今回はページパラメータが原因だったけど、ブラウザの戻るボタンで元の画面が復元されない原因はもっといろいろあると思う。でも、それらは結局のところ「既存のインスタンスを変更したとき」状態が復元できなくなるというところに集約されることになる。