Как правильно устранить несоответствие между моделью, контроллером и представлением в Grails?

Конечно, может случиться так, что мой первый проект Grails представляет собой сумасшедшее несоответствие между моей моделью данных и представлением, которое хотят дизайнеры пользовательского интерфейса.

Вот упрощенная формулировка проблемного пространства:

В продуктовом магазине есть три ингредиента: морковь, сельдерей и помидоры. Цель приложения — сохранить список покупок пользователя: сколько из них нужно купить.

Веб-дизайнеры хотят добиться этого с помощью нескольких HTML-выборов, поэтому вы выбираете из раскрывающегося списка, какой ингредиент вы хотите купить, а затем указываете количество рядом с ним. Если вы хотите больше ингредиентов, вы щелкаете ссылку JavaScript, которая добавляет больше SELECT.

В дизайне указано, что все раскрывающиеся списки одинаковы, а количество строк не ограничено. Таким образом, вы можете получить обратно форму с 5 строками, соответствующими 3 морковям, 9 сельдереям, 2 сельдереям, 5 морковям и 1 помидору.

Что я «должен» произвести из этого, так это заказ на 8 морковей, 11 сельдерей и один помидор.

Не вдаваясь во все аргументы о том, почему это плохой дизайн пользовательского интерфейса, я хочу понять на практике, как сопоставить модель/контроллер с представлением при таком несоответствии, как для отправки, так и для окончательного редактирования сохраненной отправки.

Моя первоначальная идея такова:

  • For inbound data, construct a fresh map in the Controller out of the parameters and some logic to add up the values correctly into three new key/value pairs, passing that new map into the bindData method instead of the request params map itself.
  • For presenting the view for edit, use an afterInterceptor to rewrite that part of the model into the correct number of these SELECTs, recognizing that my original 5-line order will become three lines when it's presented for editing.

Однако, когда я прочитал об объектах Command, мне стало интересно, не будет ли это лучшим подходом.

Я прочитал много страниц в Интернете, но не вижу никаких решений для такого несоответствия MVC.

Если оставить в стороне очевидный ответ (борьба с дизайнерами), как с этим справится "Grails"?


person Eliot Levitt    schedule 22.04.2011    source источник


Ответы (1)


Я думаю, ваша первоначальная идея должна сработать. Командный объект был бы хорош для переноса логики построения объектов предметной области из методов контроллера, но НЕ ТРЕБУЕТСЯ. Это может привести к более легкому чтению кода и более легкой проверке, если вы когда-нибудь добавите больше информации в свой список покупок (имя, дату и т. д.). Но что-то без объекта cmd должно работать, и я не думаю, что это неправильно...

ВСП:

<g:form .......>
<div><g:select name="ingredient" from="${['Carrots','Celery','Tomato']}"><g:textField name="amount"/></div>
<div><g:select name="ingredient" from="${['Carrots','Celery','Tomato']}"><g:textField name="amount"/></div>
<div><g:select name="ingredient" from="${['Carrots','Celery','Tomato']}"><g:textField name="amount"/></div>
<div><g:select name="ingredient" from="${['Carrots','Celery','Tomato']}"><g:textField name="amount"/></div>
</g:form>

Контроллер:

def saveCart = {
  def shoppingList = [:]
  def ingredients = params.list('ingredient')
  def amounts = params.list('amount')

  ingredients.eachWithIndex() { obj, i ->
     if (shoppingList.containsKey(obj)) {
       shoppingList[obj] = shoppingList[obj] + amounts[i]
     } else {
       shoppingList[obj] = amt[i]
     }
  }

  // shoppingListshould have everything you need now
  ....
  ....
}
person Nick Larson    schedule 22.04.2011
comment
Спасибо! Теперь я чувствую себя лучше. :-) - person Eliot Levitt; 29.04.2011