Grails在“创建”和“保存”

时间:2016-03-14 05:40:43

标签: grails

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

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

class Customer {
    String name;
    String email;
    String address;
    String mobile;
}

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

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

在控制器中:

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

但是现在你还没有在所有字段中填写表单!在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>

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

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

1 个答案:

答案 0 :(得分:5)

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

def doSomething(Integer magicNumber) {
    println "The magic number is $magicNumber"
}

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

<g:textField name="magicNumber" value="${magicNumber}" />

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

复杂类型(如域对象)被视为command objects。对于数据绑定,命令对象以与基本对象类似的方式起作用。请注意,在您的代码中,保存操作如何将Customer实例作为参数?在幕后,Grails获取HTTP请求参数并将这些参数绑定到给定对象的属性,在本例中为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
}