2016-07-19 4 views
0

У меня есть простой Groovy метод, который использует MarkupBuilder Groovy для печати HTML, очень упрощенный вариант ниже:Вызов метода из в Groovy DSL

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

Рассмотрите следующий код, который отлично подходит для меня, используя 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") 
Смежные вопросы