Spring MVC - выпадающий выбор объекта - без первичного идентификатора - PullRequest
16 голосов
/ 11 ноября 2010

Довольно распространенный вариант использования возникает, когда есть список объектов Java, из которых можно сделать выбор в веб-форме - обычно вы используете первичный ключ объекта в качестве значения, чтобы контроллер мог либо выполнить поиск или просто привязать ключ к любому объекту, созданному / обновленному.

Моя проблема в том, что список на выбор не является постоянными объектами с ключами, это бизнес-модели из сервиса, которые не имеют разумного способа извлечь их на основе содержащихся данных. Ниже приведен некоторый псевдо-код, в котором на страницу передается список Foo, и мы можем легко сообщить контроллеру onSubmit имя Foo, но что, если есть другие поля Foo, которые необходимо отправить?

Контроллер:

referenceData() {
    ...
    List foos = fooService.getFoosForBar( bar )
    return { 'foos', foos }
}

JSP:

<form>
   ...
<spring:bind path="formData.foo">
    <select name="<c:out value="${status.expression}" />">
        <c:forEach items="${foos}" var="foo">
            <option value="<c:out value="${foo.name}"/>">
                <c:out value="${foo.name}"/>
            </option>
        </c:forEach>
    </select>
</spring:bind>
   ...
</form>

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

Мой вопрос: существует ли какая-либо стандартная практика для достижения этой цели? Или я должен просто придумать свой собственный способ сделать это? Я бы предпочел не изобретать колеса, если это возможно, и это, на первый взгляд, настолько распространено, что простое использование не может быть лучшим подходом.

Ответы [ 2 ]

6 голосов
/ 11 ноября 2010

Исходя из ваших ограничений, вы должны закодировать другие элементы данных foos в качестве значения опции. <option label="${foo.name}" value="${foo.encodedValues}"/> Метод encodedValues может выглядеть примерно так:


    private String SEPARATOR = ",";

    public String getEncodedValues()
    {
        final StringBuffer returnValue = new StringBuffer();

        returnValue.append(field1);
        returnValue.append(SEPARATOR);
        returnValue.append(field2);
        returnValue.append(SEPARATOR);
        returnValue.append(field3);

        return returnValue.toString();
    }

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

3 голосов
/ 11 ноября 2010

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

<spring:bind path="formData.fooIndex">
  <select name="<c:out value="${status.expression}" />">
    <c:forEach items="${foos}" var="foo" varStatus="i">
        <option value="<c:out value="${i.index}"/>">
            <c:out value="${foo.name}"/>
        </option>
    </c:forEach>
  </select>
</spring:bind>

В вашем обработчике POST используйте foos.get(formData.getFooIndex()) Если foos может меняться между запросами GET и POST, вам нужно поместить foos в сессию, чтобы вы определенно ссылались на тот же объект в вашем обработчике POST, что и в обработчике GET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...