从Groovy DSL中调用方法

时间:2016-07-19 23:01:06

标签: groovy

我有一个简单的Groovy方法,它使用Groovy的MarkupBuilder来打印HTML,下面是非常简化的版本:

void writeHtmlFile(<args>) {
  def writer = new FileWriter(fileName.toFile())
  def html = new MarkupBuilder(writer)

  html.mkp.yieldUnescaped '<!DOCTYPE html>'
  html.mkp.xmlDeclaration(version: "1.0", encoding: "utf-8")
  html.html {
    head { ... }
    body(id: 'main') {
      h1 "Report Title"
    }      
  }
  writer.flush()
  writer.close()
}

这很有效。假设我想在执行一些计算的h1之后调用一个方法,并向MarkupBuilder添加更多内容。如何将被调用方法中定义的元素添加到MarkupBuilder中?这是我尝试过的不会引起异常的内容,但也不起作用(生成的HTML没有<h2>元素):

Closure testNested() {
  println '---'
  return { h2 "here's a subheading" } 
}

// .... other stuff from above example not repeated ...
html.html {
    head {...}
    body(id: 'main') {
      h1 "Report Title"
      testNested()
    }      

我知道我可以很容易地内联。我试图加深对Groovy如何在DSL中使用闭包和代理的理解,显然我错过了一些东西。

1 个答案:

答案 0 :(得分:1)

使用Groovy 2.4.5考虑下面的代码,它对我来说很好。

构建器模式有点棘手,因为它可以被视为分层数据和/或代码,具体取决于您的观点。通过练习,可以根据需要切换视角。

import groovy.xml.*

void testNested(def html) {
    html.h2("here's a subheading from testNested")
}

void writeHtmlFile(def fileName) {
  def writer = new FileWriter(fileName)
  def html = new MarkupBuilder(writer)

  html.mkp.yieldUnescaped '<!DOCTYPE html>'
  html.mkp.xmlDeclaration(version: "1.0", encoding: "utf-8")
  html.html {
    body(id: 'main') {
      h1 "Report Title"
      testNested(html)
    }
  }
  writer.flush()
  writer.close()
}

writeHtmlFile("out.html")