Pregunta

Tengo una lista de Team los objetos que tienen un Integer seed de la propiedad.Quiero editar todos los equipos de semillas a la vez, en un único formulario.Estoy seguro que Grails apoya indexado parámetros, pero no puedo conseguir que funcione.

Aquí es lo que tengo, y funciona, pero me estoy saltando a través de camino demasiado muchos aros y tiene que haber una mejor manera.

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>

controlador:

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

¿No es eso terrible?Demasiado ruido.¿Cómo puedo hacer algo a lo largo de las líneas de:

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

Es decir, ¿cómo puedo mapa de parámetros con nombre team[0].seed, team[0].id, team[1].seed, team[1].id para una Lista?

En Rayas sólo puede tener un List<Team> de la propiedad y se acaba el trabajo.Yo no esperamos menos de Grails!;-)

Gracias de antemano por su ayuda.

¿Fue útil?

Solución 2

Finalmente descubrí cómo hacer esto sin travesuras.

Olvídate del parámetro oculto y solo usa la ID del equipo en el parámetro semilla. En el SGP:

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

Luego, en el controlador:

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

Funciona como un encanto.

Otros consejos

params es mucho más que un Mapa, es un GrailsParameterMap que automáticamente se acumula sub-Mapa de estructuras basadas en la división de los nombres de los parámetros por '.'.Usted puede tomar ventaja de esta mediante la siguiente sgp:

<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:no hay ninguna [] en el nombre de los atributos.El controlador es bastante simple de usar un poco de negro Grails magia :

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

La primera operación findAll los filtros de todos los parámetros con un punto en el interior.El resto es un mapa de mapas de la celebración de la id de fila en k y el id y seed en v.

Espero que esto responda a su pregunta.

En 2015 .... Grails ahora funciona de manera un poco diferente y es posible que te encuentres con cadenas en lugar de los submapas esperados. Tengo algo que hacer al hacer
algo así como ...

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

EDITAR: Por cierto ...

entradas que tienen el mismo nombre, como

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

Se ponen en una Lista SI se envían más de uno. Entonces, si ambos de los anteriores se verificaron

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

Obtendría una lista.

Pero si solo uno está marcado, NO obtienes una Lista (al menos en la versión de Grails que uso), obtienes un solo valor.

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

Eso significa en un controlador, si tuviera que hacer algo como

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

Lanzaría un error si solo se enviara un elemento. Una forma maravillosa de evitar esto es

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

Si el parámetro está configurado y no es una lista, coloca el valor en la lista vacía; Si se establece el parámetro y una lista, el operador más agregará todos los valores individuales a la lista vacía; si el parámetro no está configurado, agregará dos listas vacías juntas, lo que creará una sola lista vacía.

No estoy seguro de si esto ayuda, pero podría usar un cierre con él como:

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

Probablemente podría crear una lista desde esta instancia de salida de HTML. o cree su formulario con él.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top