2013年9月14日土曜日

Play Framework 2 のテンプレートでScalaの記述方法


基本的に次の3つだけ覚えていれば大抵のことはできる。
  • テンプレートの中でScalaのコードを埋め込むには'@{}'で囲む(Playの文法)
  • '@{}'の戻り値は、scala.xml.Elemやそのコレクションを返せばよい(Playの文法)
  • Scalaのxmlリテラルの中でScalaのコードを埋め込むには'{}'で囲む(これはScalaの文法)

例1
    @{
      for( x <- List(1, 2, 3, 4) if x%2 == 0 ) yield <div> {x*10} </div>
    }

@{}スコープの中では、Scalaの記法をすべて使えるので、変数や関数を定義してもよい。

例2
    @{
      val list = List(1, 2, 3, 4)
      for {
        x <- list
        if x%2 == 0
      } yield <div> {x*10} </div>
    }

ただし、別のスコープで定義した変数は使えない。

例3 これはダメ!
    @{
      val list = List(1, 2, 3, 4)
    }

    @{
      for {
        x <- list
        if x%2 == 0
      } yield <div> {x*10} </div>
    }

scala.xml.Elemやそのコレクションを返さなければならないので、foreachとかは使えない。

例4 これはダメ!
    @{
      List(1, 2, 3, 4).withFilter( _ % 2 == 0 ).foreach { x => <div> {x*10} </div> }
    }

mapを使えばよい

例5
    @{
      List(1, 2, 3, 4).withFilter( _ % 2 == 0 ).map { x => <div> {x*10} </div> }
    }

ちなみに、withFilterは、mapの中で評価されるので、ループが1度済む。
したがって、filterしてmapなどをするときは、withFilterを使ったほうがよい。
for式の中では、if式を使うと、このwithFilterが定義されていれば呼ばれ、なければfilterが呼ばれる。

その他にも規則はあるが、それはより簡単に記述するためのヘルパー的なものなので
覚えてなくても問題ない。

例えば、前述の例1を次のように書くことができる。

例6
    @for( x <- List(1, 2, 3, 4) if x%2 == 0 ) {
      <div> @(x*10) </div>
    }

例1との違いは'@{}'を使わずに'@'を使っているところ。
これは、Scalaを記述するスコープを定義するのではなくて、Scalaの記法や値を呼び出す為に使われる。
したがってScalaの記法や値を使う場所には、すべて'@'が必要。'x*10 -> @(x*10)'のように。

また、yieldを使っていないところも違う。
playが自動的にyieldを付加してくれるようだ。

次のようにも記述できる。

例7
    @List(1, 2, 3, 4).withFilter( _ % 2 == 0 ).map { x => <div> @{x*10} </div> }

このように、スコープを定義しなくていいので、少しだけ簡単に記述できる。

0 件のコメント:

コメントを投稿