单击列表元素将javascript对象添加到spring表单

时间:2013-03-23 20:59:48

标签: jquery spring-mvc

我得到了一个从ajax调用创建的产品列表。此列表显示产品的名称和产品编号。 现在,我想通过单击产品列表中的列表元素将产品添加到表单中。

我正在使用spring mvc,因此表单使用了一个后备对象,需要填充表单中的数据。我想要添加的产品需要包含在后备对象列表中。

在表格中我还想计算总价。所以我需要的信息比产品清单中的信息要多。

我宁愿不将它作为json发布到后端,而只是使用@ModelAttribute。

在列表中点击表单时,是否可以以某种方式将完整的对象(产品)提供给表单?

希望我能够很好地解释自己,只要问一下。

以下是源代码:

$(document).ready(function() {
    $.getJSON('/oms/ajax/products', function(data) {  
        $.each(data, function(key, obj) {
            $('#productList').append('<li onclick=\"addProduct(' + obj.productName + ')\">' + obj.productName + '</li>');
        });
    });
});

function addProduct(name) {
    $('#orderItems').append('<li><input type=\"text\" name=\"order.lineItems[i]\" value=\"' + name + '\" /></li>');
}

public class OrderDTO {
    private List<OrderItemDTO> lineItems;
    /** getters and setters **/
}

public class OrderItemDTO {

    private String productCode;
    private String productName;
    private String description;
    private Float price;
    private Integer quantity;
    /** getters and setters **/
}

1 个答案:

答案 0 :(得分:0)

您需要做的是摆弄Form的DOM,添加和删除项目作为隐藏的输入字段。

Spring MVC按子脚本处理项目集合。这同样适用于List和Maps。列表:

<form:form modelAttribute="myModel">
   <form:hidden path="myListItems[0].name" />
   <form:hidden path="myListItems[1].name" />

   <form:hidden path="myMapItems['key1'].name" />
   <form:hidden path="myMapItems['someOtherKey'].name" />
</form:form>

这显示了将两个项目添加到列表或将两个项目添加到地图的常规方法。这使用Spring JSTL标记来构建表单。但是,您需要动态执行此操作,因此您将添加如下内容:

这就是Spring将如何生成上面的第二个列表项。使其工作的关键是使name属性正确。基本上,所有Spring JSTL标记都会生成某种表单输入。让事情发挥作用的最好方法是使用JSTL标记查看它是如何做到的,然后简单地复制生成的HTML标记。

一旦掌握了如何正确输入输入,现在只需编写一些JavaScript即可动态地向表单添加正确的输入。看起来你正在使用jQuery,所以你可以做类似的事情:

var myModel= $('#myModel);
$("<input />",{
  type: 'hidden',
  id: 'myListItems1.name',
  name: 'myListItems[1].name',
  value: 'someValue'
}).appendTo(myModel);

此处,#myModel是表单的生成ID。我们只是创建一个输入元素,并将其附加到表单中。很简单。

然而,这是您遇到问题的地方。 Spring MVC使用简单的setter来获取/设置Model Attribute中的值。这意味着您可以轻松地在List / Map中获取和设置值,但这也意味着如果Model属性在Session中,Spring MVC不会删除已存在的项。我的意思可以在下面的例子中解释。

假设您的用户在其订单中添加了3个商品并进行了预览。一旦它到你的控制器往返,你现在在Model Atttribute的集合中有3个项目(索引为0,1和2的元素,如果它是一个列表,你的数字是连续的)。现在让我们假设用户决定他不想要第2项(索引1),并将其删除。因此,您的JavaScript自然会从表单中删除该项目。但是,当用户提交时,即使表单不再包含索引1处的项目,它仍然在模型属性的集合中。这是因为Spring MVC只会设置从表单提交传入的内容。它没有跟踪未设置的事物。

所以,你要做的就是删除它会以某种方式跟踪它们。我有两种方法可以做到这一点。第一种是将删除标志添加到我的集合中的对象。该标志是一个简单的布尔值,当为true时,Controller / Service层知道该项已被删除并忽略它。在JavaScript中实现它的方式是,在删除项目时,您只需替换/添加删除标志的另一个隐藏输入并将其设置为“true”。

第二个选项是在删除时移动所有项目,以便所有合法项目都是1-N。提交表单后,您将发送“有效”计数以及模型属性(作为单独的RequestParam或模型属性中的值直接)。然后,Controller / Service层知道列表中应该有多少,并且可以修剪掉不属于的列表。

我可以告诉你,无论你走哪条路,让所有这些都能很好地运作是一项挑战,你需要对Spring如何工作有一个坚定的理解。我强烈建议编写一些简单的测试应用程序,看看Spring生成的内容(特别是在View中),并尝试着解决它。

至于如何实现所有这些,完全取决于你想要如何编写代码。我倾向于尝试限制我在View中保留的数据量,因此我的方法可能只是在订单中发送项目编号和数量列表。我认为这对于订购系统尤其重要,因为人们可以操纵你的JavaScript,而一些邪恶的人最终会改变购物车中商品的价格并最终剥夺你。永远不要相信浏览器发送的内容。