9

グリッド ビューの 1 つのページでコレクションのコレクションを編集する Grails (1.0.4) アプリを開発しています。Spring MVC のインデックス付きパラメーターの処理のみに依存して、非常にうまく機能するようになりました。ただし、1 つのことを除きます。

グリッドのブール値 (または、さらに言えばブール値) はチェックボックスで設定できますが、設定を解除することはできません。つまり、チェックボックスをオンにして更新すると、値は 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 のバグを見つけましたが、1.0.2 で修正済みとしてマークされており、そこで説明されている問題のメカニズム (隠しフィールド名のアンダースコアが間違った場所に置かれている) は私の場合には存在しません。

理由は何ですか?

4

5 に答える 5

4

これは Julius Huang という人が grails-user メーリング リストで提案した解決策です。これは再利用可能ですが、HTML では残念ながら送信されない未チェックのチェックボックスに対する「false」応答を非表示フィールドに入力するために JavaScript に依存しています。

カスタムTagLibでボックスのチェックを外すと(true -> false)、「false」を送信するようにGSPをハックします。

デフォルトでは、checkBox はチェックを外すと何も送信しないため、checkBox をイベント ハンドラとして使用しますが、代わりに隠しフィールドを送信します。

Controller の「params」は「false」→「true」をそのまま扱えるようになっています。例えば。コントローラーではすべてが同じままです。

GSP でのカスタム タグの使用法 (サンプルの usedfunc_F は「true」)、

<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>
于 2009-03-01T13:13:42.710 に答える
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 自体を変更する必要はありませんが、再利用できません (おそらく、追加の作業を行うことで再利用できます)。

于 2009-03-01T13:08:59.447 に答える
1

最も簡単な回避策は、デバッガーを接続して、Grailsが値の入力に失敗する理由を確認することだと思います。Grailsがオープンソースであることを考えると、ソースコードにアクセスできるようになり、その解決策を見つけたら、バージョンにパッチを適用できます。

また、ブール値へのバインドに関連する問題に言及しているこの他のバグGRAILS-2861を見つけました(スレッドのMarcのコメントを参照してください)。それがまさにあなたが説明している問題だと思います。

于 2009-02-26T00:26:24.640 に答える
1

問題を示す小さなサンプル アプリを作成し、それを Grails バグに添付します (または新しいバグを作成します)。ここにいる誰かがあなたのサンプル アプリをデバッグできるかもしれません。あるいは、バグが実際には修正されていないことを示しているでしょう。

于 2009-02-25T12:03:48.077 に答える
0

これを試して、ログをDEBUGに設定し、問題が表示されない場合は最初の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

これにより、パラメータ設定がいつどのように失敗するかを正確に確認し、おそらく回避策を見つけることができます。

于 2009-02-28T02:53:33.240 に答える