Вопрос

У меня есть список Team объекты, имеющие Integer seed свойство.Я хочу редактировать семена всех команд одновременно, в одной форме.Я конечно что Grails поддерживает индексированные параметры, но я не могу заставить его работать.

Вот что у меня есть, и это работает, но я перепрыгиваю способ слишком много обручей, и должен быть лучший способ.

гсп:

<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].seed, team[1].id в список?

В Полосы ты можешь просто иметь List<Team> собственность, и она будет просто работать.Я не ожидаю меньшего от Grails!;-)

Заранее спасибо за вашу помощь.

Это было полезно?

Решение 2

Наконец-то я понял, как это сделать без всяких махинаций.

Забудьте о скрытом параметре и просто используйте идентификатор команды в исходном параметре.В ГСП:

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

Примечание:в атрибутах имени нет [].Контроллер теперь довольно прост с использованием черной магии Грааля:

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

Первая операция findAll отфильтровывает все параметры с точкой внутри.Остальное - это карта карт, содержащих идентификатор строки. k и id и seed в 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"/>

Вносятся в список, ЕСЛИ представлено более одного.Итак, если оба вышеперечисленных пункта были проверены

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

Вы получите список.

Но если отмечен только один, вы НЕ получите список (по крайней мере, в версии 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)
  }

Если был отправлен только один элемент, возникнет ошибка.Один отличный способ обойти это -

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

Если установлен параметр, а не список, значение помещается в пустой список;Если параметр установлен и представляет собой список, оператор плюс добавит все отдельные значения в пустой список;если параметр не установлен, два пустых списка будут добавлены вместе, что создаст один пустой список.

Не уверен, поможет ли это, но вы можете использовать с ним замыкание, например:

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

Вероятно, вы могли бы создать список из этого вывода HTML.или создайте с его помощью свою форму.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top