在Play / Scala中;我很困惑为什么这不会编译:
@(tabNames: Seq[String])
@isActive(idx: Int) = {
@if(idx < 1) {
"active"
} else {
""
}
}
<ul class="nav nav-tabs">
@for((tab, idx) <- tabNames.zipWithIndex) {
@views.html.generic.navLi("tab" + idx.toString, tab, isActive(idx))
}
</ul>
错误如下:
发现:play.twirl.api.HtmlFormat.Appendable [错误](其中 扩展到)play.twirl.api.Html [error] required:String [error]
@ views.html.generic.navLi(“tab”+ idx.toString,tab,isActive(idx))
它无法识别对模板调用中isActive
的调用,而我尝试了多种变体,例如@isActive(idx)
,isActive(@idx)
${isActive(idx)}
(按照建议here)等。此模板生成导航栏,传入标签名称并检查是否nav li
应为active
(由类名/ JS配置)。
在另一个模板调用中调用函数时,似乎语法必须不同 - 我无法正确理解。
答案 0 :(得分:2)
请注意
之间@
用法的细微差别
@isActive(idx: Int) = {
@if(...
@isActive(idx: Int) = @{
if(...
可重用的纯代码块可以具有任意返回类型。在您的情况下,要将String
作为返回类型,您可以写:
@isActive(idx: Int) = @{
if(idx < 1) {
"active"
} else {
""
}
}
答案 1 :(得分:1)
Play documentation is a little light in this area;虽然声明&#34;功能&#34;当然是可行和有用的。在一个旋转模板中,返回类型似乎被锁定(有效地)Html
- 即你的&#34;块&#34; (正如文档中所述)必须呈现HTML。
如文档中所建议的,最快的解决方案是将逻辑重定位到Scala类中;对于这样简单的事情,object
是完成这项工作的最简单方法,即:
package views
object ViewHelper {
def isActive(idx: Int):String = {
if(idx < 1) {
"active"
} else {
""
}
}
}
和
<ul class="nav nav-tabs">
@for((tab, idx) <- tabNames.zipWithIndex) {
@views.html.generic.navLi("tab" + idx.toString, tab, ViewHelper.isActive(idx))
}
</ul>
这种方法的优点包括可测试性和可重用性。请注意避免被ViewHelper
可以做的事情带走 - 数据库查找等在这里是个坏主意! : - )