Grails 3.3.1使用域对象参数的控制器操作 - 数据如何绑定?

时间:2017-10-02 19:07:49

标签: grails data-binding controller

This question看起来有些类似,但是当那个Domain对象是一个Controller动作参数时,那里的提问者试图理解一对多数据绑定是如何工作的。

我想了解一下,当Domain类作为Controller动作的参数提供时,调用了哪些方法。考虑默认的更新操作:

def update(MyDomain myDomain) {
    if (myDomain == null) {
        notFound()
        return
    }

    try {
        myDomainService.save(myDomain)
    } catch (ValidationException e) {
        respond myDomain.errors, view:'edit'
        return
    }

    request.withFormat {
        form multipartForm {
            flash.message = message(code: 'default.updated.message', args:
                [message(code: 'myDomain.label', default: 'MyDomain'), myDomain.id])
            redirect myDomain
        }
        '*'{ respond myDomain, [status: OK] }
    }
}

导致上述Controller操作范围的事件序列是什么?我的最佳猜测如下,但我想确认。

def someActionWrapper() {
    MyDomain instance = MyDomain.get(params.id)
    instance.properties = params
    update(instance)
}

认为它必须要去DB以获取表单上没有的任何字段,然后用表单上的任何值覆盖,然后调用实际的控制器动作。

修改

当提出这个问题时,库的当前版本:

  • Grails 3.3.1
  • Groovy 2.4.12

1 个答案:

答案 0 :(得分:4)

请参阅https://github.com/grails/grails-core/blob/96c530ab4400f28a4cc0001b2bacbbce1e360cc1/grails-plugin-controllers/src/main/groovy/grails/artefact/Controller.groovy#L345

简而言之......

// This is pseudocode but it addresses the broad strokes of what you are asking about...
MyDomain md
if(params.id) {
    md = MyDomain.get(params.id)
} else if (request.method == 'POST') {
    md = new MyDomain()
}

if(md) {
    def doBinding = true
    if(params.id) {
        if(!(request.method in ['PUT', 'POST', 'DELETE'])) {
            doBinding = false
        }
    }

    if(doBinding) {
        // params won't necessarily be used here
        // if the request has a body, it will be used
        bindData md, params
    }

    // subject md to dependency injection

    // if md is Validateable then call .validate() on it
}

callToTheOriginalAction(md)