![](/img/trans.png)
[英]Concatenate strings from an object in th:each with Thymeleaf
[英]thymeleaf posting current object from th:each
这是我第一次使用 thymeleaf,我遇到了一个我似乎无法解决的奇怪问题。 最小样本:
考虑以下 Controller 映射以列出数据库中的所有用户:
@GetMapping("/users")
public String listUsers(Model model) {
model.addAttribute("users", userRepository.findAll());
return "users";
}
在用户视图中,我想列出用户,并为每个用户添加一个按钮以获取该特定用户的详细信息:
<table>
<thead>
<tr><th>Name</th></tr>
</thead>
<tbody>
<form th:each="user : ${users} th:action="@{/user}" th:object="${user}" method="post">
<tr>
<td th:text="${user.getUserName()}">Name</td>
<td><input type="submit" value="Details" /></td>
</tr>
</form>
</tbody>
</table>
因此,由于 users 是一个 List,我最初的想法是为该列表中的每个用户创建一个表单,并将当前 ${user} 绑定到 th:object。 然后在 controller 映射中了解详细信息(因为在此期间可能已更改):
@PostMapping("/user")
public String userDetails(@ModelAttribute User user, Model model) {
model.addAttribute("user", userService.findUserById(user.getId()));
return "userDetails";
}
现在我的问题是它不起作用。 ModelAttribute 是 controller 中的 null。 我一直在阅读有关 forms 的 thymeleaf 文档,但无法弄清楚为什么我不能在不将隐藏字段中的所有用户属性添加到表单的情况下从当前迭代中发布用户。 我可能会尝试做一些完全疯狂的事情,但老实说我不知道......对我有什么建议吗? :)
@Update:经过无数次重写后,我解决了以下问题:
@GetMapping("/users/{id}/details")
public String user(@RequestParam Integer userId, Model model) {
model.addAttribute("user", userService.findUserById(userId));
return "userDetails";
}
这意味着我只想获取用户的 ID。 为此,我创建了以下模板:
<form th:each="user: ${users}" th:action="@{/users/{user_id}/details(user_id=${user.id}})}" method="post">
<tr>
<td th:text="${user.userName}">Name</td>
<td><input type="submit" value="Details" /></td>
</tr>
</form>
现在,这导致
原因:org.thymeleaf.exceptions.TemplateProcessingException:无法解析为表达式:“@{/users/{user_id}/details(user_id=${user.id}})}”(模板:“users” - 第 13 行,第 44 栏)
我还尝试了带有隐藏文本字段的旧 post 方法,并在 controller 中使用了 th:object="${user.id}" 它是 null。 我在用户上留下了 th:object,而在 user.id 上有唯一的隐藏字段,在 controller 用户是 null id 字段未设置。 如果我尝试将 th:field 用于任何事情,我会再次收到 thymeleaf 异常:
原因:org.attoparser.ParseException:执行处理器'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor'时出错(模板:“用户”-第16行,第44列)
我向每一位 web 开发人员致以最崇高的敬意。 我一直讨厌与 web 开发相关的任何事情,老实说,这甚至不希望我开始喜欢它。 这是完全的疯狂:)
由于您使用的是 spring 引导和 thymeleaf。
您必须使用输入名称将 map 输入到 model 属性。 所以如果你想传递一个用户的id,输入的名字必须是“user.id”。 您可以手动执行此操作,也可以使用标准方式执行此操作,即使用th:field
。
th:field
将为您的输入呈现适当的名称。 它引用了命令 object 您在表单元素中使用th:object
设置的命令,如果您使用*{...}
语法,因此如果您的“用户”object 有一个“id”属性,您将绑定它与*{id}
.
它在您当前代码中的工作方式是
<form th:each="user : ${users} th:action="@{/user}" th:object="${user}" method="post">
<tr>
<td><input type="text" th:field="*{id}"></td>
<td><input type="submit" value="Details"></td>
</tr>
</form>
编辑:尽管如此,正如某些人在评论中所说,您应该将完整的 object 保存在绑定的隐藏输入中,这样您就可以在 controller 中恢复它(如果由于某种原因您需要完整的 ZA8CFDE6331BD59EB2AC96F8911C4B66),或者,仅绑定 id,使用 String/Integer/whatever 作为 model 属性,而不是“用户”object。
Edit2:如果您的 th:fields 使用它,则需要传递“用户”属性。
@GetMapping("/users")
public String listUsers(Model model) {
model.addAttribute("user", new User());
return "users";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.