そこで、クラシックな通常の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 件のコメント:
コメントを投稿