我正在尝试使用数据绑定通过表单更新hasMany
关系,但我在params
中获得的数据似乎不正确。
域类:
class CustomerSite {
static hasMany = [dhrs:DeviceHistoryRecord];
static mapping = {
id generator:'sequence', params:[sequence:'cs_seq']
}
...
}
修改视图:
...
<g:select name="dhrs" id="dhrs"
from="${DeviceHistoryRecord.list()}"
multiple="multiple"
optionKey="id"
value="${customerSiteInstance?.dhrs}"/>
控制器:
def update = {
def customerSiteInstance = CustomerSite.get( params.id )
if(customerSiteInstance) {
customerSiteInstance.properties = params
String flashMsg = new String();
flash.message = "";
if(!customerSiteInstance.hasErrors() && customerSiteInstance.save()) {
flash.message += "Customer Site ${customerSiteInstance.toString()} updated"
redirect(action:show,id:customerSiteInstance.id)
}
else {
flash.message = flashMsg
render(view:'edit',model:[customerSiteInstance:customerSiteInstance])
}
}
else {
flash.message = "Customer Site not found with id ${params.id}"
redirect(action:edit,id:params.id)
}
}
这给了我一个错误:
错误200:org.springframework.beans.NotReadablePropertyException:bean类的无效属性'currentDeviceData'[java.lang.String]:Bean属性'currentDeviceData'不可读或具有无效的getter方法:返回类型是getter匹配setter的参数类型?
在控制器代码的这一行:
if(!customerSiteInstance.hasErrors() && customerSiteInstance.save()) {
这对我没有任何意义,但我做了一些愚弄(很多,实际上),并最终发现g:select
正在将一系列索引传递给params。
视图输出我认为看起来正确的代码:
<select name="dhrs" id="dhrs" multiple="multiple" >
<option value="2421" >801122</option>
<option value="2422" >801123</option>
...
如果我要在列表的索引0和索引1处选择项目,那么它不会传入一组“2421”&amp;像我期待的那样“2422”。它正在传递“0”和“1”。更糟糕的是,在我运行之后,当我回到编辑页面并再次运行时,这次选择索引8处的内容,它将具有“8”......但也是“0”和“1” “从上次开始。
在这里看一下,我找到了Selecting multiple values from select tag - Grails,其中有一些其他的想法,包括做出这样的改变:
<g:select name="dhrs.id"
from="${DeviceHistoryRecord.list()}"
multiple="multiple"
optionKey="id"
value="${customerSiteInstance?.dhrs*.id}"/>
但这给了我一个遗漏的方法错误,虽然它确实解决了索引而不是返回实际值的问题。
关于这里发生了什么以及如何解决它的任何想法?
BTW,我正在运行Grails的1.0.4版本。是的,我很想升级它,但我不能。
谢谢!
答案 0 :(得分:1)
我花了更多时间在这上面,得到了部分解决方案。 这就是我最终得到的结果:
<g:select name="dhrsX.id"
from="${DeviceHistoryRecord.list()}"
multiple="multiple"
optionKey="id"
value="${customerSiteInstance?.dhrs*.id}"/>
请注意dhrsX
- 而不是dhrs
。这样,我可以在CustomerSite
对象中设置它们之前手动查找每个。唯一的复杂因素是,如果用户选择了一个项目,dhrsX
包含String
;如果用户选择了多个项目,则dhrsX
包含String
个列表。为了解决这个问题,我需要在尝试直接使用它们之前重新打包选择结果。
def update = {
def customerSiteInstance = CustomerSite.get( params.id )
if(customerSiteInstance) {
customerSiteInstance.properties = params
customerSiteInstance.dhrs.clear()
for(thisDHR in params.dhrsX) {
def value = thisDHR.getValue()
def ArrayList<String> list = new ArrayList<String>();
if (value instanceof String) {
list.add(value)
} else {
for(oneValue in value) {
list.add(oneValue)
}
}
for(aDHR in list){
DeviceHistoryRecord rec = DeviceHistoryRecord.get(aDHR)
if (rec != null) {
customerSiteInstance.addToDhrs(rec)
} else {
print(thisDHR + " NOT FOUND!")
}
}
}
...
现在单一选择和多项选择工作......但仍有一个小问题。尽管在添加新选择之前在clear()
上调用dhrs
,但仍保留先前的选择。但是,我并不认为这几乎要复杂。
答案 1 :(得分:0)
在g:中选择使用:
value="${customerSiteInstance?.dhrs?.id}"
问号代替星号。这就是我的“多选”的方式。