为什么输出"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(")匹配。
为每个方法生成的代码略有不同。
def h:play.api.templates.Html = {
_display_(
Seq[Any](format.raw("""<br />"""))
)
}
def i = {{Html("<br />")}}
用于创建h
的_display_
方法最终对传入的Seq
的所有元素执行foldLeft
这导致:
Html("") + Html("<br />")
事实证明,Html
case类是由一个可变的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
}
这意味着text
的值只会被设置为第一个Html
的text
的值。无论何时通过+
方法创建新的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"
也许可以尝试进行字符串匹配?
@h.toString() match {
case "" => {html is empty}
case _ => {html has content}
}