Grails 标记中的默认正文行为

Default body behaviour in a Grails tag

我正在尝试实现一个标签,如果将 none 作为参数传递,则该标签必须呈现默认正文。这是我的第一次尝试:

def myDiv = { attrs, body ->
  out << '<div class="fancy">'
  if (body) //this approach doesn't work cause body is a closure that is never null
     out << body()
  else
     out << 'default content'
  out << '</div>'
}

那么我们会有2个简单的使用场景。

1) <g:myDiv/> 内容正文不存在,应呈现:

<div class="fancy">
   default content
</div>

2) <g:myDiv> SPECIFIC content </g:myDiv> 内容主体存在,应呈现:

<div class="fancy">
   SPECIFIC content
</div>

在这种情况下最好的使用方法是什么?

我在 tagLib 中打印了 "body" 的 class 以了解更多信息。

println body.getClass() // outputs: class org.codehaus.groovy.grails.web.pages.GroovyPage$ConstantClosure

这是一个GroovyPage.ConstantClosure

当您在您的条件下检查 'body' 时,它是一个关闭。如果您使用单个标签 <g:tester/> 正文似乎不存在,您可以使用 ConstantClosure 的 asBoolean() 并且它将 return false。

def tester = {attrs, body ->
  println body.asBoolean()  // prints: false
  if (body) {
    println "body"
  } else {
    prinltn "no body"
  }
}
// outputs : "no body"

当我使用两个标签时 <g:tester></g:tester> 输出是 "body" 所以我尝试了以下操作:

def tester = {attrs, body ->
  println "**$body**"      // prints:  **
                           //          **
  println body.asBoolean() // prints:  true
  println body().size()    // prints:  1
}

我猜 body 包含一些 return 字符或白色 space。

我最好的解决方案是调用方法 body() 这个 return 是一个字符串,你可以在它上面调用 trim() 并在 groovy 真实的条件下检查它

def tester = {attrs, body ->
  if (body().trim()) {
    println "body"
  } else {
    println "no body"
  }
}  // outputs : "no body" in all scenarios except when body contains something relevant.