Domanda

Ho un elenco di Team oggetti che hanno una proprietà Integer seed. Voglio modificare tutti i semi delle squadre contemporaneamente, in un'unica forma. Sono sicuro che Grails supporta parametri indicizzati, ma non riesco a farlo funzionare.

Ecco quello che ho, e funziona ma sto saltando attraverso modo troppi cerchi e ci deve essere un modo migliore.

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>

Controller:

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

Non è terribile? Troppo rumore. Come posso fare qualcosa del genere:

params.teams.each { t ->
  def team = Team.get(t.id)
  team.seed = t.seed
}

Cioè, come posso mappare i parametri denominati team[0].seed, team[0].id, team[1].seed, team[1].id a un elenco?

In Stripes puoi semplicemente avere una proprietà List<Team> e funzionerà. Non mi aspetto di meno dal Grails! ; -)

Grazie in anticipo per il tuo aiuto.

È stato utile?

Soluzione 2

Alla fine ho capito come farlo senza shenanigans.

Dimentica il parametro nascosto e usa semplicemente l'ID squadra nel parametro seed. Nell'SPG:

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

Quindi, nel controller:

params.teams.seeds.each { teamId, seed ->
  def team = Team.get(teamId.toInteger())
  team.seed = seed.toInteger()
  team.save()
}
redirect(action:list)

Funziona come un fascino.

Altri suggerimenti

params è più di una normale mappa, è una GrailsParameterMap che costruisce automaticamente strutture di sub-mappe basate sulla divisione dei nomi dei parametri per '.'. Puoi trarne vantaggio usando il seguente 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: non c'è [] negli attributi del nome. Il controller ora è piuttosto semplice usando un po 'di magia nera di Grails:

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

La prima operazione findAll filtra tutti i parametri con un punto all'interno. Il resto è una mappa di mappe che contiene l'ID riga in k e id e seed in v.

Spero che questo risponda alla tua domanda.

Nel 2015 .... Grails ora funziona in modo leggermente diverso e potresti trovarti a imbatterti in stringhe piuttosto che nelle mappe secondarie previste. Ho qualcosa su cui lavorare facendo
| qualcosa come ..

params.nested.each{
               if(!it.getKey().contains('.')){
                 //to get a map rather than a string...    
                  params.nested[it.getKey()];
               }
           };

MODIFICA: A proposito ...

input che hanno lo stesso nome, come

  <input name="item.choice" type="checkbox" value="3" />
  < input name="item.choice" type="checkbox" value="4"/>

Vengono inseriti in un elenco SE ne viene inviato più di uno. Quindi, se entrambi i precedenti sono stati controllati

   <input name="item.choice" type="checkbox" value="3" checked />
   < input name="item.choice" type="checkbox" value="4" checked/>

Otterresti un elenco.

Ma se viene selezionato solo uno, NON si ottiene un Elenco (almeno nella versione grails che uso), si ottiene un singolo valore.

     <input name="item.choice" type="checkbox" value="3" checked />
     < input name="item.choice" type="checkbox" value="4" />

Ciò significa che in un controller, se dovessi fare qualcosa del genere

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

Sarebbe un errore se fosse inviato un solo oggetto. Un modo efficace per aggirare il problema è

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

Se il parametro è impostato e non un elenco, inserisce il valore nell'elenco vuoto; Se il parametro è impostato e un elenco, l'operatore più aggiungerà tutti i singoli valori all'elenco vuoto; se il parametro non è impostato, verranno aggiunti due elenchi vuoti insieme, creando un unico elenco vuoto.

Non sono sicuro se questo aiuta ma potresti usare una chiusura come:

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

Probabilmente potresti creare un elenco da questo instabile di output HTML. o crea il tuo modulo con esso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top