我有一个具有
Team
属性的 Integer seed
对象列表。我想以一种形式一次编辑所有团队的种子。我 确定 Grails 支持索引参数,但我无法让它工作。
这是我所拥有的,它有效,但我正在跳过way太多的箍,必须有更好的方法。
gsp:
<g:form action="setSeeds">
...
<g:each in="${teams}" status="i" var="team">
<input type="hidden" name="teams[${i}].id" value="${team.id}">
<input type="text" size="2" name="teams[${i}].seed" value="${team.seed}">
</g:each>
</g:form>
控制器:
def setSeeds = {
(0..<30).each { i ->
def team = Team.get(Integer.parseInt(params["teams[${i}].id"]))
team.seed = Integer.parseInt(params["teams[${i}].seed"])
}
redirect(action:list)
}
这不是很糟糕吗?太多的噪音。我该怎么做:
params.teams.each { t ->
def team = Team.get(t.id)
team.seed = t.seed
}
也就是说,我如何将名为
team[0].seed
、team[0].id
、team[1].seed
、team[1].id
的参数映射到列表?
在Stripes中,您可以只拥有一个
List<Team>
属性,它就可以正常工作。我对 Grails 的期望不低! ;-)
params
不仅仅是一个普通的 Map,它是一个 GrailsParameterMap
,它基于用“.”分割参数名称自动构建子 Map 结构。您可以通过使用以下 gsp 来利用这一点:
<g:form action="seed">
<g:each in="${teams}" status="i" var="team">
<input type="hidden" name="teams.${i}.id" value="${team.id}">
<input type="text" size="2" name="teams.${i}.seed" value="${team.seed}">
</g:each>
<g:submitButton name="update" value="Update" />
</g:form>
注意:名称属性中没有 []。使用一些黑色 Grails 魔法,控制器现在非常简单:
log.error "params = ${params}"
params.teams.findAll {k,v -> !k.contains(".")}.each { k,v ->
bindData(Team.get(v.id), v)
}
第一个操作
findAll
过滤掉所有带点的参数。其余的是一张包含k
中的行id和id
中的seed
和v
的地图的地图。
我希望这能回答你的问题。
我终于想出了如何在没有任何恶作剧的情况下做到这一点。
忘记隐藏参数,只需在种子参数中使用团队 ID。在普惠制中:
<g:form action="setSeeds">
...
<g:each in="${teams}" var="team">
<input type="text" size="2" name="teams.seeds.${team.id}"
value="${team.seed}">
</g:each>
</g:form>
然后,在控制器中:
params.teams.seeds.each { teamId, seed ->
def team = Team.get(teamId.toInteger())
team.seed = seed.toInteger()
team.save()
}
redirect(action:list)
工作起来很有魅力。
2015年....
Grails 现在的工作方式有点不同,您可能会发现自己遇到了字符串而不是预期的子映射。我通过做一些事情来工作
像..
params.nested.each{
if(!it.getKey().contains('.')){
//to get a map rather than a string...
params.nested[it.getKey()];
}
};
编辑:顺便说一句......
具有相同名称的输入,例如
<input name="item.choice" type="checkbox" value="3" />
< input name="item.choice" type="checkbox" value="4"/>
如果提交的不止一个,则将其放入列表中。所以如果以上两项都被检查了
<input name="item.choice" type="checkbox" value="3" checked />
< input name="item.choice" type="checkbox" value="4" checked/>
你会得到一份清单。
但是如果只检查一个,你不会得到一个列表(至少在我使用的 grails verison 中),你得到一个单一的值。
<input name="item.choice" type="checkbox" value="3" checked />
< input name="item.choice" type="checkbox" value="4" />
这意味着在控制器中,如果我要做类似的事情
params['item.choice'].each{
def item=Item.get(it)
}
如果只提交一个item会报错。解决这个问题的一种绝妙方法是
([]+(params['item.choice']?:[])).each{
def item=Item.get(it)
}
如果设置的参数不是列表,则将值放入空列表;如果设置了参数和一个列表,加号运算符会将所有单独的值添加到空列表中;如果未设置参数,它将把两个空列表加在一起,从而创建一个空列表。
不确定这是否有帮助,但您可以像这样使用闭包:
<g:each in="${teams}">
<p>id: ${it.id}</p>
<p>seed: ${it.seed}</p>
</g:each>
你可能会从这个输出 html 的过程中构建一个列表。或用它建立你的表格。