目次

Version 3, last updated by mads379 at Nov 29 21:38 UTC

MVC (どうしても必要な場合)

「MVC を使いたい」という要望は、これまでに何度となく耳にしています。率直に言って、View First なアプリケーションの方が保守も容易で、より対話性に優れた Web アプリケーションを作成できると思います。ですが、Lift には柔軟性があるので、開発者が望むアプリケーション構築の方法を選択肢として提供することも可能です。

Lift 2.2-M1 では MVCHelper というトレイトが導入されました。Lift の RestHelper を使えば、パターンマッチングを利用してシンプルな REST サービスを構築できますが、それと同様に、新しく導入された MVCHelper を使うと、MVC スタイルのコントローラを作ることができます。次に示すのは、id が “time” の要素に現在の時刻を挿入する簡単な例です。


import net.liftweb.http._
import net.liftweb.util._
import Helpers._

object RootController extends MVCHelper {
  // index (home) ページ上の時刻を更新します.
  serve {
    case "index" :: Nil =>
    // id が "time" の要素の内容を、現在の日付と時刻で置き換えます.
    "#time *" #>Helpers.formattedTimeNow
  }
}

serve メソッドは、PartialFunction[List[String], MVCResponse] を引数に取ります。このメソッドでは、サービス提供の道すじを定義します。Scala の PartialFunction は、最初の引数の型に一致するパターンのことで、パターンが一致する場合、関数は => の右辺を返します。

MVCResponse は、以下の型からの暗黙の変換を行うトレイトです。

  • Unit — URL に対応するテンプレートを一切のトランスフォームなしに実行します。
  • CssBindFunc — URL に対応するテンプレートをロードし、CSS セレクタトランスフォームを適用します。
  • NodeSeq — XHTML レスポンス。
  • LiftResponse — センドバックする LiftResponse。
  • 上記の Box または Option

UnitCssBindFunc の場合、URL に対応するテンプレートがロードされ、CssBindFunc が適用された後、テンプレートは Lift の通常のレンダリングパイプラインを介して実行されます。

返された NodeSeq は、Lift のテンプレート機構を介して実行されます。次に例を示します。

serve {
  case "foo" :: _ =>
    for {
      template<-TemplateFinder.findAnyTemplate("bar" :: Nil)
    } yield ("#id" #>"frog").apply(template)
}

パターンから値を取り出すこともできます。

serve {
  case "show_param" :: param :: Nil =>
    "#param_value" #>param
}

値を指定して for-comprehension を使うこともできます。

serve {
  case "user_name" :: user_id :: Nil =>
    for {user<- User.find(user_id)} yield "#user_name" #>user.firstName
}

Scala の抽出子を使って、抽出子から値を計算することもできます。

serve {
  case "user_name" :: User(user) :: Nil =>
    "#user_name" #> user.firstName
}

最後に注意点を掲げます。MVCHelper オブジェクトは次のように Boot.scala の中でフックしておかなければなりません。

LiftRules.dispatch.append(MyController) // ステートフル
LiftRules.statelessDispatch.append(MyController) // ステートレス (セッションなし)

以上みてきたとおり、MVC がどうしても必要な場合には、Lift で MVC を使うことができます。