【问题标题】:Closure in grails controller not picking up argumentsgrails控制器中的关闭不接受参数
【发布时间】:2014-02-01 23:21:17
【问题描述】:

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

例如,我想巩固一下:

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)
}

当调用renderJson() 时,问题发生在doRequest()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,我正在创建我一开始就试图避免的样板代码。

【问题讨论】:

    标签: grails groovy closures


    【解决方案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)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      相关资源
      最近更新 更多