grails 2.3动态形式的一对多数据绑定

时间:2014-09-08 13:53:46

标签: grails data-binding one-to-many

我正在使用 Grails 2.3.11 。我在保存一对多动态表单时遇到了问题。

我提到了这个问题Grails one-to-many databinding with dynamic forms

由于我无法在上述帖子中添加评论,因此我发布了一个新问题。所以不要将其标记为重复。

我根据此博客创建了动态表单http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/

在我之前使用 Grails 2.2.3

的应用程序中,这同样适用于我

域类:

联系班级

package blog.omarello

import org.apache.commons.collections.FactoryUtils
import org.apache.commons.collections.list.LazyList

class Contact {

    static constraints = {
        firstName(blank:false)
        lastName(blank:false)
    }
    String firstName
    String lastName
    String nickName
    List phones = new ArrayList()
    static hasMany = [ phones:Phone ]

    static mapping = {
        phones cascade:"all-delete-orphan"
    }
}

电话课程

package blog.omarello

class Phone {
    int index
    String number
    PhoneType type
    boolean deleted
    static transients = [ 'deleted' ]
    static belongsTo = [ contact:Contact ]

    /* Constraints & Enum */

}

控制器操作:

@Transactional
def save(Contact contactInstance) {
    println 'params: -> '+params
    println '------------------------------------------------------------'
    println 'params.phones: -> '+params?.phones
    println '------------------------------------------------------------'
    println 'params.firstName: -> '+params?.firstName
    println '------------------------------------------------------------'
    println 'params.lastName: -> '+params?.lastName
    println '------------------------------------------------------------'
    println 'params.nickName: -> '+params?.nickName

    if (!contactInstance.save(flush: true)) {
        flash.error = message(code: 'default.not.created.message', args: [message(code: 'contact.label', default: 'Contact')])
        render(view: "create", model: [contactInstance: contactInstance])
        return
    }

    request.withFormat {
        form multipartForm {
            flash.message = message(code: 'default.created.message', args: [message(code: 'contact.label', default: 'Contact'), contactInstance.id])
            redirect contactInstance
        }
        '*' { respond contactInstance, [status: CREATED] }
    }
}

当我提交表单时,我在控制台中没有收到任何错误。 输入表单字段名称为 phones [0] .number,phones [1] .number, ...

控制台:

params: -> [lastName:Developer, phones[0].number:123456789, phones[0]:[id:, deleted:false, new:true, number:123456789, type:H], phones[1].number:987654321, phones[1]:[id:, deleted:false, new:true, number:987654321, type:H], phones[1].deleted:false, create:Create, phones[0].id:, phones[0].deleted:false, phones[1].id:, phones[1].type:H, nickName:admin, phones[0].type:H, phones[0].new:true, firstName:Grails, phones[1].new:true, action:save, format:null, controller:contact]
------------------------------------------------------------
params.phones: -> null
------------------------------------------------------------
params.firstName: -> Grails
------------------------------------------------------------
params.lastName: -> Developer
------------------------------------------------------------
params.nickName: -> admin

我不确定为什么 params.phone Grails 2.3.11 中显示为null 有人帮我解决了这个问题。 提前谢谢。

2 个答案:

答案 0 :(得分:2)

数据绑定似乎有问题。如果它是新手机,请尝试删除参数中的id:。用grails 2.3.7测试并在我的项目中使用它。

以下是我在_phone.gsp

中所做的更改
    <div id="phone${i}" class="phone-div" <g:if test="${hidden}">style="display:none;"</g:if>>
        <g:if test="${phone?.id != null}">
            <g:hiddenField name='phones[${i}].id' value='${phone?.id}'/>
        </g:if>
        ...
    </div>

答案 1 :(得分:1)

从我所看到的,LazyList.decorate(...)不能在Grails 2.3+中用来绑定动态创建的多对一对象。我遇到了和你一样的问题。我正在将Grails 1.3项目升级到2.7,并且该项目的特定部分无法正常工作。经过大量的键盘更新,我意识到一个有效的解决方案是在控制器内执行绑定。由于我的项目所基于的数据库结构,我不想传回动态创建的子对象的计数,因此我使用具有足够高索引的循环来捕获所有用例。我不能为我的生活弄清楚如何将变量插入到参数中的数组的参数中,例如param.'field [可变]”。

工作原理是将其作为列表捕获,如下所示。然后你可以迭代,而不必在你的控制器中为每个数组索引求助于一大块蛮力。

这是我项目的一个例子。 。

<强>域

class CalculatorScenario {

列出&lt;“CalculatorScenarioIncome&gt; calculatorScenarioIncome

}

<强>控制器

def scenario = new CalculatorScenario()
        scenario.properties = params
        scenario.agent = getAgent()

        //Iterate through the income sources
        for (int i = 0; i < 30; i++) {

            //Due to the vagaries of the GrailsParameterMap, we must retrieve the incomeSource as a list of lists
            def incomeSourceList = params.list('expandableCalculatorScenarioIncome[' + i + ']')

            //Break down the lists
            def incomeSource
            for (each in incomeSourceList) {
                incomeSource = each
            }

            //Append the many Incomes to the Parent
            if (incomeSource) {
                CalculatorScenarioIncome income = new CalculatorScenarioIncome(scenario: scenario)
                income.amount = Double.parseDouble(incomeSource.amount)
                income.ownerType = incomeSource.ownerType
                income.incomeSourceType = incomeSource.incomeSourceType
                income.deleted = incomeSource.deleted
                income.startAge = Integer.parseInt(incomeSource.startAge)
                income.endAge = Integer.parseInt(incomeSource.endAge)
                scenario.calculatorScenarioIncome.add(income)
            }
        }

        log.info stop

它很乱,但它有效。