Grails在"create"和"save"之间更新的实例

Orl*_*doL 1 grails

我想知道,在脚手架控制器和视图中,您在"创建"页面中填写的字段如何在保存操作之前更新到您的域类实例.我在Grails 2.4.4上.

举个例子,我有一个名为Customer的类,我生成控制器并以默认方式查看所有内容.

class Customer {
    String name;
    String email;
    String address;
    String mobile;
}
Run Code Online (Sandbox Code Playgroud)

当您运行应用程序并在生成的绿色样式索引页面中,单击"创建新客户"时,将创建一个客户实例,因为链接将转到"创建"操作.

<ul>
    <li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
    <li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

在控制器中:

def create() {
    log.info "A customer object is created here.";
    Customer c=new Customer(params)
    respond c
}
Run Code Online (Sandbox Code Playgroud)

但是现在你还没有填写所有领域的表格!在create.gsp中填写表单后,该链接将直接指向"保存"操作.

<g:form url="[resource:customerInstance, action:'save']" >
    <fieldset class="form">
        <g:render template="form"/>
    </fieldset>
    <fieldset class="buttons">
        <g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
    </fieldset>
</g:form>
Run Code Online (Sandbox Code Playgroud)

但是在保存操作中,我看到与表单中的字段设置字段无关.它在哪里完成?

@Transactional
def save(Customer customerInstance) {
    if (customerInstance == null) {
        notFound()
        return
    }
    if (customerInstance.hasErrors()) {
        respond customerInstance.errors, view:'create'
        return
    }
    customerInstance.save flush:true
    //omit everything after save here
}
Run Code Online (Sandbox Code Playgroud)

dpc*_*ady 5

Grails使用数据绑定自动为您完成此操作.Grails控制器可以采用两类参数:基本对象和复杂对象.默认行为是在适用的情况下按名称将HTTP请求参数映射到操作参数.例如,假设我们有一个像这样的控制器:

def doSomething(Integer magicNumber) {
    println "The magic number is $magicNumber"
}
Run Code Online (Sandbox Code Playgroud)

以及包含如下字段的视图:

<g:textField name="magicNumber" value="${magicNumber}" />
Run Code Online (Sandbox Code Playgroud)

当表单提交给doSomething操作时,Grails将自动获取magicNumber请求参数,将其从String转换为Integer并将其传递给操作.

复杂类型(如域对象)被视为命令对象.对于数据绑定,命令对象以与基本对象类似的方式起作用.请注意,在您的代码中,保存操作如何将Customer实例作为参数?在幕后,Grails获取HTTP请求参数并将这些参数绑定到给定对象的属性,在本例中为a Customer.从文档:

在执行控制器操作之前,Grails将自动创建命令对象类的实例,并通过绑定请求参数来填充其属性.

换句话说,Grails将查看所有传入的请求参数,并尝试将这些参数绑定到您已声明为该操作的参数的对象上的属性.此外,它还会为您执行验证.它基本上与以下相同:

@Transactional
def save() {
    Customer customerInstance = new Customer(params)
    customerInstance.validate()

    if (customerInstance == null) {
        notFound()
        return
    }
    if (customerInstance.hasErrors()) {
        respond customerInstance.errors, view:'create'
        return
    }
    customerInstance.save flush:true
    //omit everything after save here
}
Run Code Online (Sandbox Code Playgroud)