在Thymleaf中绑定列表或数组

时间:2017-06-07 14:22:00

标签: java html spring spring-boot thymeleaf

在我的网站上,我有一些复选框,每个复选框都包含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
}

2 个答案:

答案 0 :(得分:3)

下划线__是ThymeLeaf预处理表达式的语法。或者在外行人的术语中,下划线内的内容在表达的其余部分之前被处理。

这很重要,因为你的表达式使用了一个数组,并且它的${iter.index}部分给出了数组索引。

如果你很好奇,或者其他人偶然发现了这件事。 th:name与html属性name没什么区别。 ThymeLeaf引擎只会将名称属性推送到html实体或覆盖旧实体。 ThymeLeaf有很多属性,如thisth: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之前指定对象productsComparisonids字段为List<String>

说实话,我不知道下划线会做什么,如果有人可以解释,我会很高兴。