Grails: флажок не установлен на false


8

Я разрабатываю приложение Grails (1.0.4), где я хочу редактировать коллекцию коллекций на одной странице в виде сетки. Я получил его для работы достаточно хорошо в зависимости только от обработки индексированных параметров Spring MVC, за исключением одного:

Булево значение (или, если на то пошло, булево) в сетке можно установить с помощью флажка, но не отменить , т. е. когда я устанавливаю флажок и обновляю, значение равно 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" /> 

Я нашел Grails bug, который описывает именно этот эффект, но это отмечен как зафиксировано в 1.0.2, и описанный там механизм проблемы (символ подчеркивания в скрытом имени поля помещен не в то место) в моем случае отсутствует.

Любые идеи, что может быть причиной?

1

Я бы создал небольшое примерное приложение, которое демонстрирует проблему и прикрепит ее к ошибке Grails (или создаст новую). Кто-то здесь может отлаживать ваше приложение-образец, или вы обнаружите, что ошибка на самом деле не исправлена.

  0

Я думаю, вы имеете в виду «показанный» вместо «сияния». :-) 25 фев. 092009-02-25 20:35:04

  0

Слишком ленив, чтобы сделать это прямо сейчас :) Возможно, лучшее долгосрочное решение. 01 мар. 092009-03-01 13:00:26


1

Я думаю, что простейшим обходным решением было бы приложить отладчик и посмотреть, почему Grails не заполняет значение. Учитывая, что Grails является открытым исходным кодом, вы сможете получить доступ к исходному коду, и как только вы выясните решение, вы можете исправить свою версию.

Я также нашел эту другую ошибку GRAILS-2861, в которой упоминается проблема, связанная с привязкой к булевым (см. Комментарий Марка в потоке). Я думаю, это именно то, что вы описываете.

  0

К сожалению, все динамические и метапрограммирующие магии, происходящие в grails, почти невозможно отладить, если вы точно не знаете, где искать - возможно, где-то внутри Spring MVC. которого я действительно не знаю. 01 мар. 092009-03-01 13:02:16

  0

Ошибка, с которой вы связаны, - это другое дело, я думаю - в основном недоразумение, основанное на различном значении атрибута value в HTML и grails. 01 мар. 092009-03-01 13:02:59

  0

Должен признаться, что я все еще считаю, что эти два связаны :-). Посмотрев на решение, которое вы разместили ниже, похоже, проблема заключается в том, что скрытый или флажок НЕ имеет значения, которое будет передано при отправке формы (что обсуждается в билете). 01 мар. 092009-03-01 20:23:22

  0

Решение, которое вы публикуете, заставляет меня думать, что вы должны посмотреть на код пользовательского тега и посмотреть, почему атрибут value не генерируется. Как только у вас будет этот атрибут, написанный в HTML, я ожидаю, что эта проблема будет исправлена. 01 мар. 092009-03-01 20:24:47

  0

Я пытаюсь получить мнение г-на Г. и Грэма по этому вопросу. 01 мар. 092009-03-01 20:29:47

  0

Нет, проблема в том, что HTML ничего не передает для отмеченного флажка (для отмеченного, он использует «on» в качестве значения по умолчанию, если ни один не указан). Скрытое поле является обходным путем для этого. 02 мар. 092009-03-02 10:45:23

  0

И насколько я понимаю, атрибут «значение» в граале имеет совершенно иное значение, чем в HTML - в граале он определяет, следует ли устанавливать или отменять флажок в форме. В HTML это строка, отправленная на сервер, если установлен флажок. 02 мар. 092009-03-02 10:49:01

  0

@Michael: снятые флажки не передаются, если не отмечены (это нормальное поведение HTML), поэтому, если Grails полагается на какое-то значение, которое должно быть там, все, что вам нужно сделать, это добавить функцию javascript для форматирования onsubmit, которая проходит через form.elements и установите скрытое значение для тех, кто его отсутствует. 02 мар. 092009-03-02 23:33:24

  0

Предполагается, что Grails использует скрытое поле, чтобы установить флажок с таким же именем (без подчеркивания), если он не указан в параметрах запроса, который работает для регулярных полей, но по какой-то причине не работает с индексированными полями. 03 мар. 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 мар. 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      
    } 
} 

работа, не требует никаких изменений в самых Грааль, но ISN» (возможно, это может быть сделано с некоторой дополнительной работой).


3

Это решение парня по имени Юлий Хуан, предложенного в списке рассылки грайля-пользователя. Он многократно используется, но полагается на JavaScript, чтобы заполнить скрытое поле с помощью «ложного» ответа для непроверенного флажка, который, к сожалению, HTML не отправляет.

Я взломать GSP отправить "ложь", когда снимите флажок (правда -> ложь) с пользовательских TagLib.

По умолчанию CheckBox ничего не посылает, когда снимите отметку, поэтому я использую CheckBox, как обработчика события, но послать скрытое поле вместо этого.

«params» in Controller может обрабатывать «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>