我在网上搜了差不多一天,似乎无法找到解决问题的方法 我有一个名为Hobby的查找表,其中有一堆爱好(露营,远足,骑自行车等)。爱好表在引导期间填充。 Grails创建一个带有id和描述字段的爱好表。
我有一个名为Applicant的域对象。申请人可以有零个或多个爱好。我已经宣布了这样的域名:
class Applicant {
static hasMany = [hobbies:Hobby]
List <Hobby> hobbies = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(Hobby.class));
}
在我的控制器中,我正在使用页面的命令对象,允许申请人选择他们的爱好。它被定义为:
class LifestyleCommand {
List <Hobby> hobbies = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(Hobby.class));
}
我的gsp看起来像这样:
<g:each var="item" in="${Hobby.list()}" status="i">
<g:set var="newline" value="${(i % 3) == 0 ? 'newline' : ''}" />
<div class="formcheckbox columns3 ${newline}">
<g:checkBox name="hobbies_${item.id}" optionKey="id" value="${item.id}" />
<label>${item.description}</label>
</div>
</g:each>
该页面将正确显示页面中的所有爱好。但是,当我尝试将表单提交回控制器时,LifeStyleCommand对象中的列表为null。我不确定我的gsp是否正确设置了g:checkBox变量,而且我不确定我是否正确地在命令对象中声明了List。一旦我将数据发送回控制器,我要解决的下一个问题是将数据从命令对象复制到申请人。任何帮助将不胜感激。
我尝试在命令中只使用普通的List,但grails在提交表单时会抱怨类型转换。
编辑:
以下是我的工作:
class Applicant {
static hasMany = [hobbies:Hobby]
//I removed the List <hobby>... code
...
}
我的命令对象:
class LifestyleCommand {
Set <Hobby> hobbies;
}
GSP:
<g:each in="${Hobby.list()}" var="hobby">
<g:set var="checked" value="${ command?.hobbies.find{h->h.id == hobby.id } != null }" />
<g:checkBox value="${checked}" name="${ 'hobby' +'[' + hobby.id + ']'}"/>${hobby.description}</td>
</g:each>
我的新控制器代码:
Hobby.list().each{hobby->
if (params["hobby[${hobby.id}]"] == 'on') {
applicant.addToHobbies(hobby)
}
else if (applicant.getHobbies().contains(hobby)) {
applicant.removeFromHobbies(hobby)
}
}
一切正常。可能有更好的方法,我还没有进行任何重构,但让它工作是一个起点。
答案 0 :(得分:2)
问题在于您的GSP
。当您需要对象列表时,您必须为复选框保留标准名称:
<g:checkBox name="hobbies[$i].id" ... />
这将正确映射到您的命令列表。