LiftでAjax

LiftのAjaxライブラリにはjQueryが採用されていますが、あまりjQueryを知らなくても、SnippetだけでAjaxなWebアプリが組めるように工夫されています。

前回エントリの最後にちょっとだけ言及した「AjaxもSnippetだけでできますよ」的発言の補足になります。

「triggerをクリックしたら、
 placeholderをサーバサイドから返るDOMで書き換える。」

ということをやるViewとSnippetは次のようになります。

■View

<lift:surround with="admin" at="content">
  <lift:ajaxSandbox.simple>
    <f:trigger />
    <div id="placeholder" />
  </lift:ajaxSandbox.simple>
</lift:surround>

■Snippet

import _root_.scala.xml._
import _root_.net.liftweb.http._
import _root_.net.liftweb.util._
import Helpers._
import js._
import js.JE._

class AjaxSandbox {

  def simple(xhtml: NodeSeq):NodeSeq = {
    bind("f", xhtml,
      "trigger" -> SHtml.ajaxButton( "push" , doSimple _ )
    )
  }

  def doSimple(): JsCmd = {
    println("サーバーサイドの処理")
    //ブラウザの実行コマンド
    JsCmds.SetHtml( "placeholder", <h1>Ajax!</h1> )
  }
}

ボタンではなく、他のエレメントをトリガーにしたければ、

"trigger" -> <span
   onclick={SHtml.ajaxInvoke(doSimple _)._2}>Press</span>

サーバサイド関数に引数を持たせる場合は、

"trigger" -> <button
   onclick={SHtml.ajaxCall(Str("a"), doSimple _)._2}>Press</button>

def doSimple(s:String): JsCmd = {
  println( s + " passed by client")
  JsCmds.SetHtml( "placeholder", <h1>Ajax!</h1> )
}

■JsCmd/JsExp

net.liftweb.http.js.{JsCmd,JsExp}は、ブラウザで実行するJavaScriptを生成するヘルパーです。
JsCmd(のサブタイプ)を組み立てるには、JsExp(のサブタイプ)を構成要素にします。

doSimpleの戻りJsCmdは、JavaScriptに展開後ブラウザ上に返されて実行されます。

出来上がったJavaScriptは、JsCmd.toJsCmd(String型)で確認できるので、コンソールなどで試してみると良いと思います。

>mvn compile scala:console -DmainConsole=LiftConsole
scala> import _root_.net.liftweb.http._
scala> import _root_.net.liftweb.util.Helpers._
scala> import js._
scala> import js.JsCmds._
scala> import js.JE._

scala> implicit def writer( cmd:JsCmd ) = new {
    def w = println( cmd.toJsCmd )
  }
(おしりに"w"つけるとJavaScriptに展開するようにしておく)

scala> SetHtml("placeholder" , <span>Yes</span> ) w
try{jQuery("#placeholder").each(function(i) {this.innerHTML = "<span>Yes</span>"
;});} catch (e) {}


scala> JsShowId("div_id") w
jQuery('#'+"div_id").show();

scala> After( 10 minutes , JsShowId("div_id") ) w
setTimeout(function() {jQuery('#'+"div_id").show();}, 600000);

scala> JsCrVar( "name", JsVar("takeda") ) w
var name = takeda;

・・・など。複雑なJavaScriptを組もうと思ったら、JsDoWhile/JsIfとかもありますが、ぶっちゃけこんなことしていられないので、生JavaScriptのラッパー・Runを使いましょうw

scala> Run("""alert('hello')""") w
alert('hello')

JsCmd/JsExpはタイプセーフにJavaScriptを組んでやる仕組みのようです。慣れないと大変そうなので、複雑なことをやりたければ、
・Runを使う、または、
・jQueryを生でコーディングしてブラウザにロード&Runでメソッドキック
くらいで十分ではないかなと思います。

■JsExpについて補足

SHtml.ajaxCall(Str("a"), doSimple _)

で出てきたStrはJsExpのサブタイプです。
ブラウザでのJsExp(が生成したJavaScript)の実行結果が、doSimpleへの引数に渡されます。

(前の続き)
scala> implicit def writer( exp:JsExp ) = new {
    def w = println( exp.toJsCmd )
  }

scala> Str("a") w
"a"

scala> Call("some_function") w
some_function()

scala> ValById("user_name") w
document.getElementById("user_name").value

どんな動きするのかは、慣れるまではJavaScriptに展開してみないとわからない感じですが、一応jQueryは隠蔽されていて(w)重要だと思うので何度もいいますが、SnippetだけでAjaxが出来ています

トリガー設定方法は、SHtml.{ajaxButton,ajaxCall,ajaxInvoke} の他にもいろいろありますが、次回以降(自分もまだ全部は把握していません)。


コメント

コメントしてください
お名前:
入力しなければ「匿名さん」。20字以内。

メール:
入力しても表示しません

URL:
入力すればリンクが貼れます


コメント: