Если вы разместите следующий HTML-код в сценарии PHP:
<input type="hidden" name="var[0]" value="A" />
<input type="hidden" name="var[2]" value="C" />
<input type="hidden" name="var[1]" value="B" />
Вы бы в конечном итоге с переменной $_POST['var']
(это по сути HashMap), ключи / значения которого выглядят так:
[0] => "A"[1] => "B"[2] => "C"
В PHP тогда я могу сделать базовую логику массива на этом, например, я могу видеть, что count($_POST['var']) == 3
и я могу перебрать его с foreach
заявление.
Есть ли способ сделать это или что-то подобное в Grails? Я заметил, что если я передам в Grails такой же HTML, результат будет гораздо менее интуитивным, чем в PHP. Что я хочу сделать, это просто иметь возможность доступа params.var[0]
, params.var[1]
и так далее, а также быть в состоянии исследовать такие вещи, как params.var.length
,
Но это не так. Какие происходит в том, что params.var
не определено, но вместо этого я должен получить доступ request.getParameter('var[0]')
что, очевидно, довольно бесполезно.
я понимаю что я мог бы изменить свой HTML на что-то вроде этого:
<input type="hidden" name="var" value="A" />
<input type="hidden" name="var" value="B" />
<input type="hidden" name="var" value="C" />
Но это далеко от идеала, потому что тогда я должен гарантировать, что входные данные HTML всегда находятся в правильном порядке. В PHP не имеет значения, в каком порядке они отображаются, так как я могу указать это непосредственно в атрибуте name, а язык достаточно умен, чтобы позаботиться об этом.
Я что-то пропустил? Есть ли способ сделать это в Grails?
На самом деле это происходит по умолчанию при привязке данных. Увидеть http://grails.org/doc/latest/guide/theWebLayer.html#dataBinding Привязка к коллекциям и картам.
Связыватель данных может заполнять и обновлять Коллекции и Карты. В следующем коде показан простой пример заполнения списка объектов в классе домена:
class Band { String name static hasMany = [albums: Album] List albums } class Album { String title Integer numberOfTracks } def bindingMap = [name: 'Genesis', 'albums[0]': [title: 'Foxtrot', numberOfTracks: 6], 'albums[1]': [title: 'Nursery Cryme', numberOfTracks: 7]] def band = new Band(bindingMap) assert band.name == 'Genesis' assert band.albums.size() == 2 assert band.albums[0].title == 'Foxtrot' assert band.albums[0].numberOfTracks == 6 // ...
Также, если вы хотите разобраться с этим самостоятельно, вы, конечно, можете написать это сами. Например.:
params.collect{it=~/${name}\[(\d+)\]/}.findAll().collectEntries{[it.group(1).toInteger(), params[it.group(0)]]}
Других решений пока нет …