0

我得到了一个从 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 **/
}
4

1 回答 1

0

您需要做的是摆弄表单的 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 将如何生成上面的第二个列表项。使其工作的关键是正确地获取名称属性。基本上,所有的 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 使用简单的设置器来获取/设置模型属性中的值。这意味着您可以轻松地在 List/Map 中获取和设置值,但这也意味着如果模型属性在 Session 中,Spring MVC 不会删除已经存在的项目。我的意思可以在下面的例子中解释。

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

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

第二种选择是在移除时将所有物品上移,这样所有合法物品都是 1-N。提交表单后,您将发送“有效”计数以及模型属性(作为单独的 RequestParam 或直接在模型属性中的值)。然后控制器/服务层知道列表中应该有多少,并且可以修剪掉不属于的那些。

我可以告诉你,不管你走哪条路,让所有这些工作都很好是一个挑战,你需要对 Spring 的工作原理有一个深刻的理解。我强烈建议编写一些简单的测试应用程序,查看 Spring 生成的内容(尤其是在视图中),并尝试了解它。

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

于 2013-03-25T12:00:25.160 回答