2

在播放/斯卡拉;我很困惑为什么这不会编译:

   @(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 [error](扩展为) 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 配置)。

似乎在另一个模板调用中调用函数时语法必须不同 - 我无法正确理解。

4

2 回答 2

3

文档区分了

  • 可重用的代码块
  • 可重用的代码块

@请注意两者在用法上的细微差别

@isActive(idx: Int) = {
  @if(...

@isActive(idx: Int) = @{
  if(...

可重用的纯代码块可以有任意的返回类型。在您的情况下,String作为返回类型,您可以编写:

   @isActive(idx: Int) = @{
       if(idx < 1) {
           "active"
       } else {
           ""
       }
   }
于 2017-11-26T22:55:04.907 回答
1

Play 文档在这方面有点轻;虽然在 twirl 模板中声明“函数”当然是可能且有用的,但返回类型似乎被锁定(有效地)Html- 即您的“块”(如文档中所指)必须呈现 HTML。

如文档中所建议的,最快的解决方案是将逻辑重新定位到 Scala 类中;对于像这样简单的事情,anobject是完成这项工作的最简单方法,即:

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>

这种方法的优点包括可测试性和可重用性。请注意避免被 a can 做的事情冲昏头脑ViewHelper- 数据库查找等在这里是个坏主意!:-)

于 2017-11-24T02:33:10.580 回答