Tsutomu Yano
t_yano****@me*****
2010年 12月 27日 (月) 11:56:20 JST
すみません、忙しくて返事できてませんでした。 ブックマーク可能ページがマウントしたURLで表示されるのは、ページオブジェクトが作成されたときだけです。ページオブジェクトの状態がまっさらなときだけ、という言い方をしてもいいかも。 Wicketが表示しているのはHTMLではなく、Pageというオブジェクトインスタンスの状態だという点を理解した方がよいような気がするので、ちょっとオブジェクト指向的な部分の解説をしてみたいと思います。 自画面から自画面への遷移を考えるとして、 setResponsePage(Class) を呼び出すと、Classを元に、いままで表示していたページインスタンスとは別の新しいページインスタンスをClassから生成して、それを表示します。同じページクラスから出来たページ(当然同じHTMLを使っているページ)を表示しているので、これを持って「自画面」ということもできるでしょうが、オブジェクトインスタンスとしては別のページを表示しています。さっきまで表示していたページは捨てられます。逆に、新しいまっさらな状態のページオブジェクトを表示するので、URLもマウントしたものになります。 しかしインスタンスとして別のオブジェクトですから、もしsetResponsePage()する前に、ページ内のフィールドをユーザ入力値に基づいてせっせと書き換えて、よしWicketはステートフルなフレームワークだからこの状態は維持されるぞ、と思っても、遷移したとたんにその情報は失われます。違うインスタンスに遷移したからです。 情報を遷移先の新しいインスタンスに渡すには、PageParameterを使う必要があるでしょう。 setResponsePage(Class, PageParameter) ただし、この場合遷移後のURLは「/home」ではなく「/home/key/value」あるいは「/home?key=value」のようになると思います。 setReponsePage()を使わなかった場合は、意味的には次のコードに近いものになります。 setResponsePage(MyPage.this); これはまさしく、「いま使ってるインスタンスをもう一回表示してくれ」という指示になります。 この場合、表示対象となるインスタンスはいまと同じなのですから、ページのフィールドなども維持され、ページの最新状態が表示されます。 ところで、Wicketは「ユーザ入力によって状態が変わったページ」をせっせと保存して状態維持しておりまして、これをバージョンと呼びます。で、WicketといえどもURLに基づいてページを表示するので、「このページのバージョン2を表示して」というリクエストがあって初めて、そのパージョンのインスタンスを見つけて表示できるわけです。 そのため、最初に表示したページインスタンスをもう一度表示しようとすると、ブラウザ上のURLはWicketが生成した「バージョン1を表示して」という意味のURLに変わります。これが、setResponsePage()を呼び出さなかった時にURLが変わる理由です。「さっき表示してた初期状態のページじゃなくて、クリック(なりサブミットなり)で状態が変わった後の最新バージョン表示してね」というのが「setResponsePage(MyPage.this)」の意味だからです。 で、このように状態が変わったあとのページのURLというのは奇妙なものになりますが、多くの場合、それは「入力途中の、ページの一時的な状態」を表示しているに過ぎないので、ブックマークしたところで30分後には消えてますよ、という考え方みたいで、それ故途中状態のURLはブックマーク可能ではありません。ページインスタンスはセッションが切れれば消滅しますから、インスタンスをブックマークしても意味がないのです。ブックマークして意味があるのは、初めてページを表示するためのURLだけです。 でも「途中状態をブックマーク可能にする必要はないんだけど、もしブックマークしたら、バージョン0の初期状態を表示して欲しいなあ」という意見は当然のようにありました。 そのためにあるのが「HybridUrlCodingStrategy」というクラスで、ページのマウント方法を次のように変えることで使えます。 mount(new HybridUrlCodingStrategy("/home", HomePage.class)); このクラスを使ってマウントすると、ページのURLは次のような感じになります。 /home.0 /home.0.1 /home.0.2 ... 数字のところがページバージョンなどのWicket用の情報で、マウントURLも残ります。この場合、どのタイミングでもブックマークは可能です。次に表示したときに、もしもうインスタンスがセッションから消えていたら、新しいページインスタンスが生成されて表示されます。 もしどうしてもURLをすべて自分でコントロールしたいのであれば、最初の setResponsPage(Class, PageParameter)を使って、遷移のたびに次のインスタンスへPageParameterを使って自前で情報を伝達するか、Sessionを使って自分で状態維持してがんばるか、というところになるでしょう。しかしそれでは、なんとなくStrutsっぽくなってしまいますが… という感じです。 --------------------------------------------------- 矢野 勉(やの つとむ) 電子メール: t_yano****@me***** ---------------------------------------------------