2

为什么此输出“html 为空”?

@h = {<br />}

@h match {
  case Html("") => {html is empty}
  case _ => {html has content}
}

这会输出“html 有内容”吗?

@i = @{Html("<br />")}

@i match {
  case Html("") => {html is empty}
  case _ => {html has content}
}

这对我来说很重要的原因是因为在最后一个示例的常见用例中(moreScripts 和 moreStyles 等效项),第一个样式用于将一小段 html 传递到另一个模板中。然后我想根据该html是否有内容进行切换。但它总是匹配 Html("")。

4

2 回答 2

3

为每种方法生成的代码略有不同。

def h:play.api.templates.Html = {
  _display_(
    Seq[Any](format.raw("""<br />"""))
  )
}
def i = {{Html("<br />")}}

创建中使用的_display_方法h最终foldLeft对传入的所有元素执行 aSeq

这导致:

Html("") + Html("<br />")

case 类原来Html是由一个 mutable 支持的StringBuilder

case class Html(text: String) extends Appendable[Html] with Content with play.mvc.Content {
  val buffer = new StringBuilder(text)

  /**
   * Appends this HTML fragment to another.
   */
  def +(other: Html): Html = {
    buffer.append(other.buffer)
    this
  }
  override def toString = buffer.toString

  /**
   * Content type of HTML (`text/html`).
   */
  def contentType: String = "text/html"

  def body: String = toString

}

这意味着 of 的值text只会被设置为 firstHtmltext值。每当您Html通过该+方法创建一个新的时,您只需修改StringBuilder.

例如

val html = Html("1") + Html("2")
html.text == "1"
html.toString == "12"
html.body == "12"

由于它是text用于模式匹配的值,这有效地破坏了它在模式匹配中使用的能力。

例如

(Html("1") + Html("2")) match { case Html("1") => "broken" } // returns "broken"
于 2012-07-14T03:19:57.340 回答
0

也许尝试进行字符串匹配?

@h.toString() match {
  case "" => {html is empty}
  case _ => {html has content}
}
于 2012-07-12T17:16:31.097 回答