播放模板仅在使用括号调用时才有效

时间:2016-03-07 21:24:15

标签: scala playframework

我的Application控制器中有以下代码:

  def index = Action {
    var ticketsAvailable = 1
    Ok(views.html.index)
  }

当我尝试运行应用程序时,我收到此编译错误:

Cannot write an instance of views.html.index.type to HTTP response. Try to define a Writeable[views.html.index.type]

在线

Ok(views.html.index) 

但是,当我添加括号(如下所示)时,错误消失:

Ok(views.html.index()) 

为什么? 我认为,在Scala中,当没有参数时,括号的使用是可选的。

1 个答案:

答案 0 :(得分:7)

查看生成的Scala代码,看一下名为index.scala.html的简单Twirl模板(Twirl是Play模板引擎)可能是有益的:

@()

<h1>Hello, world</h1>

默认情况下,Play会将此编译为target/scala-2.11/twirl/main/views/html/index.template.scala中的Scala文件,并且,如果您将其清理一下以删除源映射(这会使模板中的编译错误转换为正确的输入文件)它看起来像这样:

package views.html
import play.twirl.api._

object index_Scope0 {
  import models._
  import controllers._
  import play.api.i18n._
  import views.html._
  import play.api.templates.PlayMagic._
  import play.api.mvc._
  import play.api.data._

  class index
    extends BaseScalaTemplate[play.twirl.api.HtmlFormat.Appendable, Format[play.twirl.api.HtmlFormat.Appendable]](play.twirl.api.HtmlFormat)
    with play.twirl.api.Template0[play.twirl.api.HtmlFormat.Appendable] {

    def apply(): play.twirl.api.HtmlFormat.Appendable = {
      _display_ {
        {
          Seq[Any](format.raw(""""""), format.raw("""<h1>hello, world</h1>"""))
        }
      }
    }

    def render(): play.twirl.api.HtmlFormat.Appendable = apply()
    def f: (() => play.twirl.api.HtmlFormat.Appendable) = () => apply()
    def ref: this.type = this
  }
}

object index extends index_Scope0.index

需要注意的重要一点是,views.html.index是一个对象,其类型为views.html.index.type,如果你没有#&#39} 39;添加parens。但是,此对象扩展了一个名为views.html.index_Scope0.index的类,该类具有apply()方法,该方法返回Html对象(或更确切地说,HtmlFormat.Appendable,这是非混淆类型。 )

如果你&#34;打电话&#34;一个Scala对象,Scala转换(或者#34; de-sugars&#34;)来调用对象上的apply()方法(这是案例类构造函数在不使用new的情况下工作的方式。)因此,如果你使用parens,你会得到一个Html对象,这是渲染的Twirl模板的结果。如果你不这样做,你只需要获得已编译的模板对象,Play不知道如何写入HTTP响应。