在我的网站上,我有一些复选框,每个复选框都包含value
属性中的ID。提交表单后,我希望有一个列表,其中包含要传递给控制器的已复选复选框的ID。这就是我想要比较n个产品的新页面。
控制器可以接受List<Long>
或long[]
。这就是我现在所拥有的:
HTML:
<form th:action="@{/comparison}" th:object="${productsComparison}" target="_blank" method="post">
<table>
<tr data-th-each="item, iter : ${items.item}">
<td>
<input type="checkbox" th:name="|productsComparison.ids[${iter.index}]|" th:value="${item.id}"/>
</td>
</tr>
</table>
我已使用适当的getter和setter添加到List<Long>
包含的控制器ProductComparison
中。提交表单后,列表始终为 null 。
控制器:
@RequestMapping("/productsPage")
public String showProducts(Model model) {
ProductsComparison productsComparison = new ProductsComparison();
model.addAttribute("productsComparison", productsComparison);
}
@RequestMapping("/comparison")
public String compareProducts(@ModelAttribute ProductsComparison productsComparison) {
System.out.println("List: " + productComparison.getIds());
// Always shows null
return "comparison";
}
public class ProductsComparison {
private List<Long> ids;
// Getters & setters
}
答案 0 :(得分:3)
下划线__
是ThymeLeaf预处理表达式的语法。或者在外行人的术语中,下划线内的内容在表达的其余部分之前被处理。
这很重要,因为你的表达式使用了一个数组,并且它的${iter.index}
部分给出了数组索引。
如果你很好奇,或者其他人偶然发现了这件事。 th:name
与html属性name
没什么区别。 ThymeLeaf引擎只会将名称属性推送到html实体或覆盖旧实体。 ThymeLeaf有很多属性,如this。 th:field
虽然是完全不同的野兽。它告诉ThymeLeaf将表单的输入绑定到后面的表单bean或模型属性th:object="${productsComparison}"
。因此,使用表达式th:field="*{ids[__${iter.index}__]}"
,Thymeleaf将调用productsComparison.getIds[0]
和相应的setter。
如果您使用任何类型的Javascript提交,请注意th:name
,您可能想要使用此功能。您很可能正在序列化表单,此方法调用创建的JSON将使用name属性。
如果您想了解有关ThymeLeaf预处理表达式的更多信息,documentation中有一点关于它。
答案 1 :(得分:0)
我终于找到了解决方案。而不是th:name
我必须使用th:field
。
th:field="*{ids[__${iter.index}__]}"
因为它的字段我不必在id之前指定对象productsComparison
。 ids
字段为List<String>
。
说实话,我不知道下划线会做什么,如果有人可以解释,我会很高兴。