Grails:复选框未被设置为false


8

我正在开发Grails(1.0.4)应用程序,我想在网格视图的单个页面上编辑集合的集合。根据Spring MVC的索引参数处理,我得到它工作得很好,除了一件事:

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

这是复选框的GSP代码:

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

这是生成的HTML:我发现一个Grails bug描述的正是这种效果

<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中标记为固定,并且在那里描述的问题机制(隐藏字段名称下划线放在错误的地方)在我的情况下不存在。

任何想法可能是什么原因?

1

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

  0

我认为你的意思是'显示'而不是'闪光'。 :-) 25 2月. 092009-02-25 20:35:04

  0

现在太懒了:)可能是最好的长期解决方案。 01 3月. 092009-03-01 13:00:26


1

我认为最简单的解决办法是附加一个调试器,看看为什么Grails无法填充该值。考虑到Grails是开源的,你可以访问源代码,一旦你找出解决方案,你可以修补你的版本。

我还发现了其他的bug GRAILS-2861,它提到了绑定到布尔值的问题(请参阅Marc在线程中的注释)。我想这正是你所描述的问题。

  0

不幸的是,所有在grails中进行的动态和元编程魔术都使得调试几乎不可能,除非您确切地知道在哪里寻找 - 可能在Spring MVC内的某处。我不知道。 01 3月. 092009-03-01 13:02:16

  0

我认为,链接到的错误是另一回事 - 基本上是基于HTML和grails中“value”属性的不同含义的误解。 01 3月. 092009-03-01 13:02:59

  0

我必须承认,我仍然相信这两者是相关的:-)。通过查看您在下面发布的解决方案,看起来问题是隐藏或复选框在提交表单时(在票证中讨论)没有值。 01 3月. 092009-03-01 20:23:22

  0

您发布的解决方案让我认为您应该查看自定义代码并查看为什么不生成value属性。一旦你将这个属性写成HTML,我希望这个问题得到解决。 01 3月. 092009-03-01 20:24:47

  0

我在这里试图让Mr.G和Graeme对这个问题的看法。 01 3月. 092009-03-01 20:29:47

  0

不,问题在于HTML没有为未经检查的复选框发送任何内容(对于选中的复选框,如果没有指定,则使用“on”作为默认值)。隐藏的领域是一个解决方法。 02 3月. 092009-03-02 10:45:23

  0

据我了解,grails中的“value”属性的含义与HTML完全不同 - 在grails中,它决定了表单中的复选框是否应该设置或取消设置。在HTML中,如果设置了复选框,则它是发送到服务器的字符串。 02 3月. 092009-03-02 10:49:01

  0

@Michael:未勾选的复选框在未选中时不会传输(这是HTML正常行为),所以如果Grails依赖某些值存在,您需要做的就是将一个javascript函数添加到表单的onsubmit中,并通过form.elements并为那些缺少它的人设置隐藏值。 02 3月. 092009-03-02 23:33:24

  0

Grails应该使用隐藏字段来推断,如果请求参数中没有出现相同名称(sans下划线)的复选框,它对常规字段起作用,但由于某种原因失败,并且索引字段失败。 03 3月. 092009-03-03 00:28:31


0

尝试了这一点,设置日志调试,弗里斯特尝试第3,如果他们不显示的问题时,他们都翻转到DEBUG:

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 

这应该让你看到什么时候以及参数设置如何失败并可能找出解决方法。

  0

Unfortunatley,我还没有在日志中发现任何可用的提示 - 它不知道如何映射“._fixiert”参数,但当然这并不存在于域模型中,因为它只是一个表示缺席“.fixiert = on”表示应该设置为false。 01 3月. 092009-03-01 13:05:53


2

这是我自己的解决方案,基本上是一个变通方法,手动做什么数据绑定Grails的应该做的事(但没有):

Map<String,String> checkboxes = params.findAll{def i = it.key.endsWith("._fixiert")} // all checkboxes 
checkboxes.each{ 
    String key = it.key.substring(0, it.key.indexOf("._fixiert")) 
    int tagIdx = Integer.parseInt(key.substring(key.indexOf('[')+1, key.indexOf(']'))) 
    int zuwIdx = Integer.parseInt(key.substring(key.lastIndexOf('[')+1, key.lastIndexOf(']'))) 
    if(params.get(key+".fixiert")) 
    { 
     dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert = true 
    } 
    else 
    { 
     dienstplanInstance.tage[tagIdx].zuweisungen[zuwIdx].fixiert = false      
    } 
} 

作品,需要的Grails本身没有变化,但是,这不是”不可重用(可能会做一些额外的工作)。


3

这是一个名叫Julius Huang的人在grails-user邮件列表中提出的解决方案。它是可重用的,但依赖于JavaScript来填充一个隐藏的字段,其中包含一个未选中的复选框的“false”响应,该复选框很遗憾不会发送。

我砍GSP送“假”时 取消选中该复选框(真 - >假)与 自定义标签库。

默认情况下,当复选框取消选中 ,所以我用的复选框作为 事件处理程序,但发送隐藏字段 ,而不是没有任何响应。

控制器中的“params”可以处理 “false” - >“true”,不需要修改任何 。例如。控制器中的所有内容仍为 。

在GSP自定义标记的使用(样品usedfunc_F是 “真”),

<jh:checkBox name="surveyList[${i}].usedfunc_F" value="${survey.usedfunc_F}"></jh:checkBox> 

这里是标签产生什么,

<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>