8

Teamプロパティを持つオブジェクトのリストがありInteger seedます。すべてのチームのシードを 1 つのフォームで一度に編集したい。Grails がインデックス付きパラメーターをサポートしていることは確かですが、動作させることができません。

これが私が持っているもので、うまくいきますが、あまりにも多くのフープを飛び越えているので、もっと良い方法が必要です.

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].seedteam[1].id

Stripesでは、List<Team>プロパティを持つだけで機能します。Grails にも期待しています。;-)

よろしくお願いします。

4

4 に答える 4

11

paramsは通常のマップ以上のものでありGrailsParameterMap、パラメーター名を「.」で分割することに基づいてサブマップ構造を自動的に構築する です。次の 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>

注意: name 属性に [] はありません。コントローラーは、黒い 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です。

これがあなたの質問に答えることを願っています。

于 2009-12-02T11:05:49.823 に答える
6

私は最終的に、何の悪ふざけもなしにこれを行う方法を見つけました。

隠しパラメーターのことは忘れて、シード パラメーターでチーム ID を使用するだけです。GSP では:

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

魅力のように機能します。

于 2009-12-09T14:02:38.667 に答える
1

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

リストが表示されます。

しかし、1つだけがチェックされている場合は、リストを取得せず(少なくとも私が使用するgrailsバージョンでは)、単一の値を取得します。

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

アイテムが 1 つだけ送信された場合、エラーがスローされます。これを回避するためのグルーヴィーな方法の1つは、

 ([]+(params['item.choice']?:[])).each{
         def item=Item.get(it)
 } 

パラメーターが設定されていてリストではない場合、値は空のリストに入れられます。パラメーターが設定されていてリストの場合、プラス演算子はすべての個々の値を空のリストに追加します。パラメータが設定されていない場合は、2 つの空のリストが追加され、1 つの空のリストが作成されます。

于 2015-03-31T17:17:55.190 に答える
-1

これが役立つかどうかはわかりませんが、次のようなクロージャーを使用できます。

<g:each in="${teams}">
     <p>id: ${it.id}</p>
     <p>seed: ${it.seed}</p>
</g:each>

おそらく、html を出力する代わりに、このリストからリストを作成できます。またはそれを使用してフォームを作成します。

于 2009-11-28T03:58:00.107 に答える