2010-11-11 9 views
17

Un caso de uso bastante común se produce cuando hay una lista de objetos Java, desde la cual se pueden hacer selecciones en un formulario web; generalmente usaría la clave primaria del object como el valor para que el controlador pueda realizar una búsqueda, o simplemente vincular la clave a cualquier objeto creado/actualizado.Spring MVC - Selección de objetos desplegables - Sin identificador primario

Mi problema es que la lista para elegir no son persistentes, los objetos con clave, son modelos comerciales de un servicio que no tienen forma razonable de recuperarlos en función de los datos contenidos. A continuación se muestra un código psuedo donde se le da una lista de Foo a la página, y podemos comunicarnos fácilmente con el controlador en Enviar el nombre de Foo, pero ¿qué ocurre si hay otros campos de Foo que se deben enviar?

controlador:

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> 

Algunos ejemplos de soluciones sería utilizar campos ocultos a presentar otras propiedades de Foo y mantenerlos sincronizados como la selección se cambia, pero yo prefiero no usar JavaScript en una situación como esta donde probablemente agregará confusión. Sin duda, hay otras maneras de lograr esto también.

Mi pregunta es, ¿existe alguna práctica estándar para lograr esto? ¿O debería crear mi propio modo de hacerlo? Prefiero no volver a inventar las ruedas si es posible, y esto es tan común que simplemente volar no puede ser el mejor enfoque.

Respuesta

7

En función de sus limitaciones, debe codificar los otros datos de los miembros de foos como el valor de la opción.
<option label="${foo.name}" value="${foo.encodedValues}"/>
El método encodedValues podría ser algo como esto:

 

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

Si usted tiene un número de selecciona que necesitan han codificado los valores, es posible que desee crear una clase que hace la codificación y decodificación de estos valores para centralizar el código.

+0

Utilicé este enfoque al registrar una carpeta personalizada en el controlador para pasar de la cadena al objeto representativo (que es el centralizado código que sugiere dwb). – Nate

3

Puede usar el índice del elemento en la lista para recuperarlo en la solicitud 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> 

En el controlador de publicar, usar foos.get(formData.getFooIndex()) Si Foos pueden cambiar entre el GET y POST peticiones, es necesario poner foos en sesión, por lo que definitivamente hacen referencia al mismo objeto en su manejador POST como lo hizo en el OBTENER controlador.

+0

No puedo volver a obtener la lista y espero que sea la misma, ponerla en la sesión no es lo ideal: si el formulario no se publica, e incluso si lo fuera, es posible que la lista solo permanezca en la sesión hasta que terminó la sesión. ¿Qué más podría hacer para permitir que el manejador de correos tenga la lista? La solicitud es a muy corto plazo, pero la sesión es a muy largo plazo – walnutmon

+0

Luego puede ordenar su objeto en el valor

Cuestiones relacionadas