2009-11-28 13 views
8

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

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> 

regolatore:

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 è questo terribile? Troppo rumore. Come posso fare qualcosa sulla falsariga di:

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

che è, come posso mappare params nome team[0].seed, team[0].id, team[1].seed, team[1].id a un elenco?

In Stripes è sufficiente avere una proprietà List<Team> e funzionerà. Non mi aspetto niente di meno da Grails! ;-)

Grazie in anticipo per il vostro aiuto.

risposta

6

Finalmente ho capito come fare questo senza imbrogli.

Dimentica il parametro nascosto e utilizza semplicemente l'ID team nel parametro seme. Nella 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> 

Poi, 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.

-1

Non sono sicuro se questo aiuta, ma si potrebbe usare una chiusura con esso come:

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

Probabilmente si potrebbe costruire una lista da questo instaed di output HTML. o costruisci il tuo modulo con esso.

+0

Sto già utilizzando una chiusura per creare un modulo. La domanda è: come posso recuperare i parametri indicizzati nel controller per creare un elenco? – foxdonut

11

params è più di una normale mappa, è un GrailsParameterMap che crea automaticamente strutture di sub-Map basate sulla divisione dei nomi dei parametri con ".". Potresti approfittare di questo utilizzando gsp seguente:

<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'è nessun [] negli attributi del nome. Il controller è ora piuttosto semplice utilizzando po 'di magia nera 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 al suo interno. Il resto è una mappa di mappe che tiene l'id riga in k e id e seed in v.

Spero che questo risponda alla tua domanda.

+2

Mi chiedo se qualcun altro ha problemi a far funzionare tutto questo. Usando grails 1.3.4, invece di ottenere la sub-mappa prevista, ottengo quella che sembra una rappresentazione in formato stringa della sub-mappa. Ad esempio, params.toString() "[filters.1.value: 123, filters: [" 1 ": [" value ":" 123 "]," 1.value ":" 123 "], action: list, controller : utente] " – bcowdery

+0

Sembra un po 'brutto, ma funziona. Grazie! –

+0

Sì, ho avuto tutti i tipi di problemi con questo nel 2015. Sembra che Grails ora restituisca tutti i valori dei parametri come stringhe, il che rende praticamente inutilizzabile la stringa 'lista di mappe' come bcowdery ha trovato anni fa. – user2782001

1

Nel 2015 .... Grails funziona un po 'diverso ora e si possono trovare te stesso in esecuzione in stringhe piuttosto che il previsto sub-maps.I avuto qualcosa su cui lavorare facendo
qualcosa di simile ..

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

EDIT: A proposito ...

ingressi 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 vengono inviati 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/> 

Si otterrebbe una lista.

Ma se solo uno è selezionato NON si ottiene un elenco (almeno nella versione Grails che utilizzo), si ottiene un valore singolo.

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

Ciò significa in un controllore, se dovessi fare qualcosa di simile

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

Sarebbe genera un errore se un solo elemento è stato presentato. Un modo groove per aggirare il problema è

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

Se il parametro è impostato e non una lista, mette il valore nella lista vuota; Se il parametro è impostato e un elenco, l'operatore più aggiungerà tutti i singoli valori alla lista vuota; se il parametro non è impostato, aggiungerà due liste vuote insieme, creando una singola lista vuota.

+0

Qualche idea sul perché questo è il caso? Perché le sub-mappe annidate sono rotte? – U47

Problemi correlati