我正在尝试使用实用程序闭包来合并控制器中的冗余代码,以执行常规异常处理程序和响应生成。
例如,我想巩固一下:
def newUser(){
def model = [:]
def errors
try{
model += [newUserObj:dao.newUser(...)]
}catch(Exception e){
errors = e.getMessage()
}
renderJson(model,error)
}
..对此:
def newUser(){
def model = [:]
def errors
doRequest(model, errors){ ->
model += [newUserObj:dao.newUser(...)]
}
}
..将样板代码移动到闭包时:
def doRequest(model, errors, clsr){
try{
clsr.call()
}catch(Exception e){
errors = e.getMessage()
}
//!! model here is null !!
renderJson(model,error)
}
调用doRequest()
时问题发生在renderJson()
; model
为空,即使我确认它已在model += [newUserObj:dao.newUser(...)]
的闭包内正确分配。
我设法通过从闭包中返回model
来解决这个问题:
def newUser(){
doRequest(){ ->
def model = [:]
def errors
model += [newUserObj:dao.newUser(...)]
[model:model, errors:errors]
}
}
def doRequest(clsr){
def model = [:]
def errors
try{
def r = clsr.call()
model = r['model']
errors = r['errors']
}catch(Exception e){
errors = e.getMessage()
}
renderJson(model,error)
}
..但这根本不像Groovy,我正在创建我试图避免的锅炉板代码。
答案 0 :(得分:1)
这是你在找什么?
import grails.converters.JSON
//Closure implementation
def doRequest(Closure clsr) {
def model = [:]
def errors = /No Error Message Yet/
try {
model = clsr(model)
} catch(Exception e) {
errors = e.getMessage()
}
renderJson(model, errors)
}
//Mimics an action method
def newUser() {
doRequest { model ->
model += [a:1] //Mimics the call to DAO in your question
//make sure to return the model after all operations completed
//model
}
}
//Mimics the render to JSON utility
private JSON renderJson(model, error) {
[model: model, errors: error] as JSON
}
//Mimics call to the action method
assert newUser().toString() ==
/{"model":{"a":1},"errors":"No Error Message Yet"}/
我可以实现doRequest()
如下所示的东西,但我没有,因为在那种情况下,模型和错误将成为类的一部分(在您的情况下,它将是Controller的全局属性),这是我们不想要的。
def doRequest(Closure clsr) {
try {
clsr.resolveStrategy = Closure.DELEGATE_FIRST
clsr.delegate = this
clsr()
} catch(Exception e) {
errors = e.getMessage()
}
renderJson(model, errors)
}