Grails数据绑定 - 带有列表的命令对象

时间:2012-03-14 20:34:39

标签: grails grails-controller

Grails 1.3.7

数据绑定问题具有List内容的命令对象。示例命令:

class Tracker {
    String name
    String description
    List<Unit> units = new ArrayList()
}

class Unit {
    String name
    Long unitMax
    Long unitMin
}

为Tracker创建GSP具有单位字段。一个例子:

<g:textField name="units[0].unitMax" value=""/>

TrackerController保存方法:

 def save = { Tracker trackerInstance ->
   trackerInstance = trackingService.saveOrUpdateTracker(trackerInstance)
 }

但是,总是java.lang.IndexOutOfBoundsException

或者,如果我将控制器更新为:

def save = {
   Tracker trackerInstance = new Tracker()
   trackerInstance.properties = params
   ....

然后groovy.lang.ReadOnlyPropertyException:无法设置readonly属性:类的属性:com.redbrickhealth.dto.Tracker 有任何想法吗?

GORM与Command对象之间的绑定似乎有区别。

也许我需要扩展并注册一个PropertyEditorSupport for Unit?

-Todd

2 个答案:

答案 0 :(得分:6)

从Groovy 1.8.7开始,List接口有一个名为withLazyDefault的方法,可以用来代替apache commons ListUtils

List<Unit> units = [].withLazyDefault { new Unit() }

每次使用不存在的索引访问Unit时,都会创建一个新的units实例。

有关详细信息,请参阅documentation of withLazyDefault。几天前我还写了一篇关于这个的小blog post

答案 1 :(得分:4)

Grails需要一个带有现有列表的命令,该命令将填充来自请求的数据。

如果您知道确切的单位数,例如3,您可以:

class Tracker {
    String name
    String description
    List<Unit> units = [new Unit(), new Unit(), new Unit()]
}

或使用来自apache commons集合的LazyList

import org.apache.commons.collections.ListUtils
import org.apache.commons.collections.Factory
class Tracker {
    String name
    String description
    List<Unit> units = ListUtils.lazyList([], {new Unit()} as Factory)
}