2010-11-11 30 views
17

Trường hợp sử dụng khá phổ biến xảy ra khi có danh sách đối tượng Java, từ đó bạn có thể thực hiện lựa chọn trên biểu mẫu web. đối tượng là giá trị để bộ điều khiển có thể thực hiện tra cứu hoặc chỉ cần gắn khóa cho đối tượng nào được tạo/cập nhật.Spring MVC - Lựa chọn đối tượng thả xuống - Không có mã định danh chính

Vấn đề của tôi là danh sách để chọn không phải là đối tượng khóa, liên tục, chúng là các mô hình kinh doanh từ một dịch vụ không có cách hợp lý để truy xuất chúng dựa trên dữ liệu chứa. Dưới đây là một số mã psuedo nơi một danh sách các Foo được đưa ra cho trang, và chúng ta có thể dễ dàng giao tiếp với bộ điều khiển onSubmit tên của Foo, nhưng nếu có các lĩnh vực khác của Foo cần phải được nộp?

điều khiển:

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> 

Một số giải pháp ví dụ sẽ được sử dụng trường dữ liệu ẩn nộp các tài sản khác Foo và giữ chúng trong đồng bộ như lựa chọn được thay đổi, nhưng tôi thích không sử dụng JavaScript trong một tình huống như thế này, nơi có khả năng sẽ gây nhầm lẫn. Chắc chắn có những cách khác để thực hiện điều này.

Câu hỏi của tôi là có tồn tại bất kỳ thực hành tiêu chuẩn nào để thực hiện việc này không? Hay tôi nên nghĩ ra cách làm như vậy? Tôi không muốn tái phát minh ra bánh xe nếu có thể, và điều này dường như rất phổ biến mà chỉ cần đánh cánh nó có thể không phải là cách tiếp cận tốt nhất.

Trả lời

7

Dựa trên những giới hạn của bạn, bạn phải mã hóa các bộ ghi dữ liệu khác của foos làm giá trị của tùy chọn.
<option label="${foo.name}" value="${foo.encodedValues}"/>
Phương pháp encodedValues có thể trông như thế này:

 

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

Nếu bạn có một số Selects rằng cần phải có mã hóa giá trị, bạn có thể muốn tạo ra một lớp mà không được mã hóa và giải mã của các giá trị này để tập trung mã.

+0

Tôi đã sử dụng phương pháp này bằng cách đăng ký một binder tùy chỉnh trong bộ điều khiển để đi từ chuỗi đến đối tượng đại diện (đó là tập trung mã mà dwb gợi ý). – Nate

3

Bạn có thể sử dụng chỉ mục của phần tử trong danh sách để đưa nó trở lại trong yêu cầu 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> 

Trong handler POST của bạn, sử dụng foos.get(formData.getFooIndex()) Nếu foos có thể thay đổi giữa GET và POST yêu cầu, bạn cần phải đặt foos trong phiên để bạn chắc chắn tham khảo cùng một đối tượng trong xử lý POST của bạn như bạn đã làm trong GET xử lý.

+0

Tôi không thể lấy lại danh sách và mong đợi nó giống nhau, đặt nó trong phiên không phải là lý tưởng - nếu biểu mẫu không được đăng, và ngay cả khi nó đã được, có thể danh sách sẽ chỉ ở lại phiên cho đến khi phiên kết thúc. Tôi có thể làm gì khác để cho phép trình xử lý bài đăng có danh sách? Yêu cầu quá ngắn hạn, nhưng phiên quá dài hạn – walnutmon

+0

Sau đó, bạn có thể sắp xếp đối tượng của mình theo giá trị

Các vấn đề liên quan