Grails:复选框未设置回false

Grails:复选框未设置回false,grails,spring-mvc,Grails,Spring Mvc,我正在开发一个Grails(1.0.4)应用程序,希望在其中编辑网格视图中单个页面上的集合集合。我只依靠Spring MVC的索引参数处理就可以让它工作得很好,除了一件事: 网格中的布尔值(或布尔值)可以通过复选框设置,但不能取消设置,即,当我选中复选框并更新时,该值设置为true,但之后当我再次编辑时,取消选中复选框并更新时,该值仍为true 这是复选框的GSP代码: <g:checkBox name="tage[${indexTag}].zuweisungen[${indexMitar

我正在开发一个Grails(1.0.4)应用程序,希望在其中编辑网格视图中单个页面上的集合集合。我只依靠Spring MVC的索引参数处理就可以让它工作得很好,除了一件事:

网格中的布尔值(或布尔值)可以通过复选框设置,但不能取消设置,即,当我选中复选框并更新时,该值设置为true,但之后当我再次编辑时,取消选中复选框并更新时,该值仍为true

这是复选框的GSP代码:

<g:checkBox name="tage[${indexTag}].zuweisungen[${indexMitarb}].fixiert" value="${z.fixiert}" />

这是生成的HTML:

<input type="hidden" name="tage[0].zuweisungen[0]._fixiert" />
<input type="checkbox" name="tage[0].zuweisungen[0].fixiert" checked="checked" id="tage[0].zuweisungen[0].fixiert"  />

我发现了一个完全描述这种效果的方法,但在1.0.2中它被标记为已修复,并且这里描述的问题机制(隐藏字段名称中的下划线放在错误的位置)在我的案例中不存在


想知道原因是什么吗?

我将创建一个小样本应用程序来演示问题,并将其附加到Grails bug(或创建一个新的)。这里可能有人能够调试您的示例应用程序,或者您会发现该错误并未真正修复。

我认为最简单的解决方法是附加一个调试器,并查看Grails为何无法填充该值。考虑到Grails是开源的,您将能够访问源代码,一旦您找到了解决方案,就可以修补您的版本


我还发现了另一个bug,它提到了与布尔值绑定相关的问题(见Marc在帖子中的评论)。我想这正是您所描述的问题。

尝试一下,将日志设置为调试,首先尝试前3个,如果它们没有显示问题,则将它们全部翻转到调试:

codehaus.groovy.grails.web.servlet="error"  //  controllers
codehaus.groovy.grails.web.pages="error" //  GSP
codehaus.groovy.grails.web.sitemesh="error" //  layouts
codehaus.groovy.grails."web.mapping.filter"="error" // URL mapping
codehaus.groovy.grails."web.mapping"="error" // URL mapping
codehaus.groovy.grails.commons="info" // core / classloading
codehaus.groovy.grails.plugins="error" // plugins
codehaus.groovy.grails.orm.hibernate="error" // hibernate integration

这应该允许您准确地看到参数设置失败的时间和方式,并可能找到解决方法

这是我自己的解决方案,基本上是一种解决方法,可以手动执行grails数据绑定应该执行的操作(但不执行):

Map checkboxes=params.findAll{defi i=it.key.endsWith(“.u fixiert”)}//所有复选框
复选框。每个{
String key=it.key.substring(0,it.key.indexOf(“.\u fixiert”))
int tagIdx=Integer.parseInt(key.substring(key.indexOf('['))+1,key.indexOf(']'))
int zuwIdx=Integer.parseInt(key.substring(key.lastIndexOf('['))+1,key.lastIndexOf(']'))
if(参数get(key+“.fixiert”))
{
dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert=true
}
其他的
{
dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert=false
}
}

这是一个名为Julius Huang的家伙在grails用户邮件列表中提出的解决方案。它是可重用的,但依靠JavaScript为未选中的复选框填充一个隐藏字段,不幸的是HTML并没有发送该复选框

我黑客GSP发送“假”时 用鼠标取消选中该框(真->假) 自定义标记库

默认情况下,复选框在 取消选中,因此我将复选框用作 事件处理程序,但发送隐藏字段 相反

控制器中的“参数”可以处理 “假”->“真”不带任何 修改。一切都还保留着 在控制器中也是如此

GSP中的自定义标记用法(示例usedfunc\u F为“真”)


下面是标签生成的内容

<input type="hidden" name="surveyList[#{i}].usedfunc_F" id="surveyList[#{i}].usedfunc_F" value="false" />
<input type="checkbox" onclick="jhtoggle('surveyList[#{i}].usedfunc_F')" checked="checked" />

Javascript

<script type="text/javascript">
function jhtoggle(obj) {
   var jht = document.getElementById(obj);
   jht.value = (jht.value !='true' ? 'true' : 'false');
}
</script>

功能切换(obj){
var jht=document.getElementById(obj);
jht.value=(jht.value!='true'?'true':'false');
}

现在懒得这么做:)这可能是最好的长期解决方案。但不幸的是,grails中所有的动态和元编程魔法使得调试几乎不可能,除非您确切地知道在哪里可以查看—可能在Spring MVC中的某个地方。我真的不知道。我认为,您链接到的bug是另一回事——基本上是基于HTML和grails中“value”属性的不同含义的误解。我必须承认,我仍然相信这两者是相关的:-)。通过查看您在下面发布的解决方案,问题似乎在于,提交表单时,隐藏或复选框没有要传输的值(这在票据上讨论)。您发布的解决方案使我认为您应该查看自定义标记代码,并了解为什么不生成value属性。一旦你用HTML编写了该属性,我希望这个问题会得到解决。我试图在这里获得G先生和Graeme先生对这个问题的意见。不幸的是,我在日志中没有找到任何有用的提示-它不知道如何映射“.\u fixiert”参数,但当然域模型中没有这个参数,因为它只是一个指示,缺少“.fixiert=on”意味着它应该设置为false。
<input type="hidden" name="surveyList[#{i}].usedfunc_F" id="surveyList[#{i}].usedfunc_F" value="false" />
<input type="checkbox" onclick="jhtoggle('surveyList[#{i}].usedfunc_F')" checked="checked" />
<script type="text/javascript">
function jhtoggle(obj) {
   var jht = document.getElementById(obj);
   jht.value = (jht.value !='true' ? 'true' : 'false');
}
</script>