質問

Teamプロパティを持つInteger seedオブジェクトのリストがあります。すべてのチームのシードを一度に、単一のフォームで編集したいと思います。 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].seedteam[0].idteam[1].seedteam[1].idという名前のパラメータをリストにマップするにはどうすればよいですか

ストライプでは、List<Team>プロパティを設定するだけで機能します。 Grailsからも期待しています! ;-)

ご協力いただきありがとうございます。

役に立ちましたか?

解決 2

ようやくシェナンガンなしでこれを行う方法を見つけました。

非表示のパラメーターを忘れて、シードパラメーターでチーム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)

チャームのように動作します。

他のヒント

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>

NB:名前属性に[]はありません。コントローラーは、いくつかの黒いGrailsマジックを使用して非常に簡単になりました。

log.error "params = ${params}"
params.teams.findAll {k,v -> !k.contains(".")}.each { k,v ->
       bindData(Team.get(v.id), v)
}

最初の操作findAllは、ドットを含むすべてのパラメーターをフィルターで除外します。残りは、kに行ID、idseedおよびvを保持するマップのマップです。

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

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

1つ以上送信された場合、リストに追加されます。したがって、上記の両方がチェックされた場合

   <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つの空のリストが一緒に追加され、単一の空のリストが作成されます。

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

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

おそらく、この出力されたhtmlからリストを作成できます。またはそれでフォームを構築します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top