关闭grails控制器没有拿起参数

时间:2014-02-01 23:21:18

标签: grails groovy closures

我正在尝试使用实用程序闭包来合并控制器中的冗余代码,以执行常规异常处理程序和响应生成。

例如,我想巩固一下:

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,我正在创建我试图避免的锅炉板代码。

1 个答案:

答案 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)
}
相关问题