そこで、クラシックな通常のHTMLフォームを使い、なおかつStatefulSnippetとして同じインスタンスが呼ばれるようなコードを書いてみました。
ソースを見る
まずはLift流に
普通にLift流に簡単なフォームを書くとこんな感じです。<lift:StatefulTest.liftForm form="POST"> <e:instance/> <e:input/> <e:submit/> </lift:StatefulTest.liftForm>
Snippetはこんな感じ。
def liftForm(in: NodeSeq): NodeSeq = { var name = "" def sayHello() = { S.notice("Hello, " + name + ". I'm " + this) redirectTo("/liftSayHello") } bind("e", in, "instance" -> Text("I'm " + this), "input" -> SHtml.text(name, i => name = i), "submit" -> SHtml.submit("say hello", sayHello) ) }
無理やり普通のformで
これと同様なフォームを、無理やり書くとこんな感じです。<lift:StatefulTest.myForm> <form action="mySayHello" method="POST"> <e:instance/> <e:key/> <e:input/> <e:submit/> </form> </lift:StatefulTest.myForm>
ポイントは、registerThisSnippet()を呼ぶ関数ブロックを、S.fmapFuncで自分で関数マップに登録してやり、そのキーをhiddenで埋め込んでやること(*1)。
def myForm(in: NodeSeq): NodeSeq = { S.fmapFunc((a: List[String]) => {registerThisSnippet()})(key => { bind("e", in, "key" -> <input type="hidden" name={key} value="_"/>, // *1 "instance" -> Text("I'm " + this), "input" -> <input type="text" name="name"/>, "submit" -> <input type="submit" value="say hello"/> ) }) }このやり方だと、セッションが続いていれば同じインスタンスのStatefulSnippetが呼ばれ、続いていない場合でも、少なくとも新しいインスタンスのStatefulSnippetで処理は行えます。(CSRFの問題がありますが…)
ソースはgithubに置きました。http://github.com/pomu0325/lift_sandbox
0 件のコメント:
コメントを投稿