lift-mapperのpaginateを使う

liftでページネートする方法。Lift-Wikiを補足する形ですが、snippetで繰り返す箇所/繰り返さない箇所が混在する場合の対処方法を紹介します。

[Lift-Wiki]Example: Paginating Mapper-based snippets with sortable headers

ソートヘッダー付のPaginateをサクッと作れるのですが、上記サンプルが中途半端なので補完してみます。

バージョンはLift1.1-M7です。まだAPI変わる可能性あるので、その辺りは注意してください。

■View

<lift:surround with="default" at="content">
<lift:userView.list>

 <nav:records/> <br/>
 <nav:first/> <nav:prev/> <nav:allpages> | </nav:allpages> <nav:next/> <nav:last/>

 <table>
  <tr>
   <th><sort:id><lift:loc>ID</lift:loc></sort:id></th>
   <th><sort:email><lift:loc>mail</lift:loc></sort:email></th>
   <th><sort:nickname><lift:loc>ニックネーム</lift:loc></sort:nickname></th>
  </tr>
  <f:users>
  <tr>
   <td><f:id /></td>
   <td><f:email /></td>
   <td><f:nickname /></td>
  </tr>
  </f:users>
 </table>

</lift:userView.list>
</lift:surround>

名前空間のnav/sortは決まっている値。

ポイントは、繰り返し表示する箇所(user行)を<f:items /> <f:users />で括っているところ。

■Snippet

import net.liftweb.mapper.view._

class UserView extends ModelSnippet[User] {

 //必須でoverride
 override val view = new ModelView( User, this )
 override def edit(xhtml: NodeSeq):NodeSeq = <h1>Edit</h1>

 val paginator =
 new Paginator(User, this, User.id,//初期ソートカラム
 "id" -> User.id, "email" -> User.email, "nickname" -> User.nickname )

 def list(xhtml: NodeSeq):NodeSeq = {

  //行繰り返し用のテンプレート<f:users></f:users>を切り出しておく
  val innerTemplate = ( xhtml \\ "users" first ).descendant(1)

  bind("f",
   paginator.paginate(xhtml), //xhtmlを->pagenate用テンプレートに変換
   "users" -> bindUsers(innerTemplate) //f:usersをrender
  )
 }

 private def bindUsers(xhtml: NodeSeq):NodeSeq = {
  paginator.page.flatMap( user => {
   bind("f", xhtml,
    "id" -> Text( user.id.toString ),
    "email" -> Text( user.email ),
    "nickname" -> Text( user.nickname ) )
  })
 }
}

snippet内で、繰り返す/繰り返さない箇所が混在するときは、ViewにしるしをつけてSnippet内で分解してやる。・・というのは自分はよく使ってる方法ですが、他にうまい方法ご存知の方はぜひ教えてください。


Paginatorにクエリを指定するには、

 Paginator#constantParams

ページの表示件数を指定するには、

 Paginator#num

に値を入れます。mapper.view.Paginatorのソースはとてもシンプルなので、継承して"流れるような"インターフェースにしたりも十分できそう。

さすがにRailsのpaginateほど美しくはないですが、満足です。


コメント
ymnk
2009/12/08
わかり易い解説ありがとうございます。
一点だけ...

> ポイントは、繰り返し表示する箇所(user行)を
> <f:items />で括っているところ。

例にあわせるとすると、<f:items /> は <f:users />
のような気がしますが、どうでしょうか?

武田ソフト
2009/12/08
ご指摘ありがとうございますっ、修正しました。

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

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

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


コメント: