浏览 3792 次
锁定老帖子 主题:Spring绑定动态列表成员
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-01-03
最后修改:2011-01-03
在添加的时候,我们根据当前条目的数量,计算新添加条目的下标。 在删除的时候,使用js将删除的条目隐藏,并将删除列表的下标记录到隐藏字段中。 这样在后台,我们只需要将删除的条目,按照记录在隐藏字段的下标删除,然后再保存即可。 关于绑定动态列表,在Spring 2.5中,不能使用普通的List,必须使用AutoPopulatingList进行绑定,否则会导致OutOfBoundException,Spring 3提供了Auto Grown的功能,但还仅限于List和Array,map和set还不能Auto Grown。 下面以一个简单的订单修改的例子说明如何进行动态列表绑定: 一个订单,有很多订单条目,用户可以修改订单,动态删除或者添加订单条目。 先看看model: 订单类,一个订单有一个订单列表: package com.qunar.advertisement.advertiser.model; import java.util.List; /** * Author: fuliang * http://fuliang.iteye.com */ public class Order { private Long id; private String name; private List<OrderItem> orderItems; public void setId(Long id) { this.id = id; } public Long getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setOrderItems(List<OrderItem> orderItems) { this.orderItems = orderItems; } public List<OrderItem> getOrderItems() { return orderItems; } } 订单条目类: package com.qunar.advertisement.advertiser.model; /** * Author: fuliang * http://fuliang.iteye.com */ public class OrderItem { private Long id; private String product; private Integer price; public void setId(Long id) { this.id = id; } public Long getId() { return id; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public void setProduct(String product) { this.product = product; } public String getProduct() { return product; } } 我们的控制器使用@ModelAttribute注解和表单绑定: package com.qunar.advertisement.advertiser.controller; import java.util.Collections; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import com.qunar.advertisement.advertiser.model.Order; import com.qunar.advertisement.advertiser.service.OrderManger; /** * Author: fuliang * http://fuliang.iteye.com */ @Controller @RequestMapping("/orders") public class OrderController { private OrderManger orderManager; @Autowired public void setOrderManger(OrderManger orderManager){ this.orderManager = orderManager; } @RequestMapping("/edit/{id}") public ModelAndView edit(@PathVariable("id") Long id){ return new ModelAndView("/orders/edit_order",Collections.singletonMap("order", orderManager.getOrderById(id))); } @RequestMapping("/update") public ModelAndView update(@ModelAttribute("order") @Valid Order order,@RequestParam(value="deletedIndexes",required=false) List<Integer> deletedIndexes){ orderManager.update(order,deletedIndexes); return new ModelAndView("/orders/home"); } } edit_order.jsp的表单和js添加、删除: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jstl/fn" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <jsp:include page="../base.jsp"></jsp:include> <head> <script src="js/jquery-1.3.1.js" type="text/javascript"></script> <title>Order Home</title> <script type="text/javascript"> function deleteItem(itemIndex){ $('#item_' + itemIndex).hide(); $('#deletedIndexes').append("<input type='hidden' name='deletedIndexes' value='" + itemIndex + "'"); } function addItem(){ var itemCnt = parseInt($('#itemCnt').val()); var newItem = '<tr id="item_' + itemCnt + '">' + '<th>订单条目' + (itemCnt + 1)+ '</th>' + '<td><input type="hidden" name="orderItems[' + itemCnt + '].id"/>' + '<input type="text" name="orderItems[' + itemCnt + '].product"/>' + '</td>' + '<td><input type="text" name="orderItems[' + itemCnt + '].price"/></td>' + '<td><a href="javascript:void(0)" onclick="deleteItem('+ itemCnt + ')">删除条目</a></td>' + '</tr>'; $('#item_' + (itemCnt-1)).after(newItem); $('#itemCnt').val(itemCnt + 1); } </script> </head> <body> <div id="form"> <form:form commandName="order" id="orderForm" action="orders/update" method="post"> <form:hidden path="id"/> <div id="deletedIndexes" style="display:none;"> </div> <input type="hidden" value="${fn:length(order.orderItems)}" id="itemCnt"/> <table> <tr> <th>订单名</th> <td colspan="3"><form:input path="name"/></td> </tr> <c:forEach varStatus="vs" items="${order.orderItems}"> <tr id="item_${vs.index}"> <th>订单条目${vs.index + 1}</th> <td><form:hidden path="orderItems[${vs.index}].id"/> <form:input path="orderItems[${vs.index}].product"/> </td> <td><form:input path="orderItems[${vs.index}].price"/></td> <td><a href="javascript:void(0)" onclick="deleteItem('${vs.index}')">删除条目</a></td> </tr> </c:forEach> <tr> <td colspan="4" style="text-align:center"> <input type="submit" value="保存"/> <input type="button" value="添加订单条目" onclick="addItem()"/> </td> </tr> </table> </form:form> </div> </body> </html> 在Serice类中我们只是简单的准备数据和打印出结果查看效果: package com.qunar.advertisement.advertiser.service; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; import com.qunar.advertisement.advertiser.model.Order; import com.qunar.advertisement.advertiser.model.OrderItem; /** * Author: fuliang * http://fuliang.iteye.com */ @Service public class OrderManger { //Simple data for test public Order getOrderById(Long id){ Order order = new Order(); order.setId(id); order.setName("手机订单"); List<OrderItem> orderItems = new ArrayList<OrderItem>(); order.setOrderItems(orderItems); OrderItem orderItem1 = new OrderItem(); orderItem1.setId(1L); orderItem1.setProduct("iPhone 4"); orderItem1.setPrice(5000); orderItems.add(orderItem1); OrderItem orderItem2 = new OrderItem(); orderItem2.setId(2L); orderItem2.setProduct("Nokia N97"); orderItem2.setPrice(4000); orderItems.add(orderItem2); return order; } /** * * @param order should be updated * @param deletedItemIndexes orderItem indexes should be deleted * 简单的在控制台打印出结果,如果存入到数据库,可以根据orderItem id * 是否为null,进行更新或者保存。 */ public void update(Order order, List<Integer> deletedItemIndexes) { if(deletedItemIndexes != null){ for(int i = deletedItemIndexes.size() - 1; i >= 0; i--){ order.getOrderItems().remove(deletedItemIndexes.get(i).intValue()); } } StringBuilder sb = new StringBuilder(); sb.append("Order Id: ").append(order.getId()).append("\tName: ").append(order.getName()).append("\n"); List<OrderItem> items = order.getOrderItems(); for (OrderItem orderItem : items) { sb.append("Item Id: ").append(orderItem.getId()).append("\tName: ").append(orderItem.getProduct()).append("\tprice: ").append(orderItem.getPrice()).append("\n"); } System.out.println(sb.toString()); } } BTW:Java的自动拆装箱要注意,特别是List#remove有两个重载的方法, remove(Object) remove(int),这个必须手工拆箱。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-01-20
如果对象成员为SET,如何绑定呢?
|
|
返回顶楼 | |
发表时间:2011-02-27
我想同问,如果成员属性是Set如何绑定呢?
|
|
返回顶楼 | |
发表时间:2011-02-27
junnyfan 写道 我想同问,如果成员属性是Set如何绑定呢?
好像不可以,绑定的需要能够按照下标访问的,而Set本身不能确保有序,所以不能下标访问。最好在VO中使用List绑定,然后和PO的Set转换一下。 |
|
返回顶楼 | |