简体   繁体   English

thymeleaf 从 th:each 发布当前 object

[英]thymeleaf posting current object from th:each

This is my first time with thymeleaf and I got across a strange problem that I can't seem to get around.这是我第一次使用 thymeleaf,我遇到了一个我似乎无法解决的奇怪问题。 A minimal sample:最小样本:

Consider the following Controller mapping to list all users from a database:考虑以下 Controller 映射以列出数据库中的所有用户:

@GetMapping("/users")
public String listUsers(Model model) {
    model.addAttribute("users", userRepository.findAll());
    return "users";
}

Inside the users view, I want to list the users and for each of them I want to add a button to get the details for that particular user:在用户视图中,我想列出用户,并为每个用户添加一个按钮以获取该特定用户的详细信息:

<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>

So, since users is a List, my original idea was to create a form for each user in that list, and bind the current ${user} to th:object.因此,由于 users 是一个 List,我最初的想法是为该列表中的每个用户创建一个表单,并将当前 ${user} 绑定到 th:object。 Then in the controller mapping for the details (since this might have been changed in the meantime):然后在 controller 映射中了解详细信息(因为在此期间可能已更改):

@PostMapping("/user")
public String userDetails(@ModelAttribute User user, Model model) {
  model.addAttribute("user", userService.findUserById(user.getId()));
  return "userDetails";
}

Now my problem is that it doesn't work.现在我的问题是它不起作用。 The ModelAttribute is null in the controller. ModelAttribute 是 controller 中的 null。 I've been reading thymeleaf's documentation on forms but can't figure out why I can't post the user from the current iteration without adding all of the user attributes in hidden fields to the form.我一直在阅读有关 forms 的 thymeleaf 文档,但无法弄清楚为什么我不能在不将隐藏字段中的所有用户属性添加到表单的情况下从当前迭代中发布用户。 I might by trying to do something completely insane, but I don't know honestly... Any tips for me?我可能会尝试做一些完全疯狂的事情,但老实说我不知道......对我有什么建议吗? :) :)

@Update: After countless rewrites I settled with the following: @Update:经过无数次重写后,我解决了以下问题:

@GetMapping("/users/{id}/details")
public String user(@RequestParam Integer userId, Model model) {
    model.addAttribute("user", userService.findUserById(userId));

    return "userDetails";
}

Meaning I only want to get the user's ID.这意味着我只想获取用户的 ID。 For this, I created the following template:为此,我创建了以下模板:

<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>

Now, this results in现在,这导致

Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "@{/users/{user_id}/details(user_id=${user.id}})}" (template: "users" - line 13, col 44)原因:org.thymeleaf.exceptions.TemplateProcessingException:无法解析为表达式:“@{/users/{user_id}/details(user_id=${user.id}})}”(模板:“users” - 第 13 行,第 44 栏)

I also tried the old post method with a hidden text field for the id and used th:object="${user.id}" in the controller it's null.我还尝试了带有隐藏文本字段的旧 post 方法,并在 controller 中使用了 th:object="${user.id}" 它是 null。 I left the th:object on user, while having the sole hidden field on user.id, in the controller User is null id field is not set.我在用户上留下了 th:object,而在 user.id 上有唯一的隐藏字段,在 controller 用户是 null id 字段未设置。 If I try to use th:field for anything, I again get a thymeleaf exception:如果我尝试将 th:field 用于任何事情,我会再次收到 thymeleaf 异常:

Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "users" - line 16, col 44)原因:org.attoparser.ParseException:执行处理器'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor'时出错(模板:“用户”-第16行,第44列)

My deepest greatest respect to every web developer there is out there.我向每一位 web 开发人员致以最崇高的敬意。 I always hated anything related to web development and honestly this doesn't want me to even start to like it.我一直讨厌与 web 开发相关的任何事情,老实说,这甚至不希望我开始喜欢它。 This is complete madness:)这是完全的疯狂:)

Since you are using spring boot and thymeleaf.由于您使用的是 spring 引导和 thymeleaf。

You've to map the input to the model attribute with the input's name.您必须使用输入名称将 map 输入到 model 属性。 So if you want to pass the id of an user, the input name has to be "user.id".所以如果你想传递一个用户的id,输入的名字必须是“user.id”。 You can do this manually, or the standard way, which is using th:field .您可以手动执行此操作,也可以使用标准方式执行此操作,即使用th:field

th:field will render the appropiate name for your input. th:field将为您的输入呈现适当的名称。 It references the command object you set with th:object in the form element if you use *{...} syntax, so if your "User" object has an "id" attribute, you'd bind it with *{id} .它引用了命令 object 您在表单元素中使用th:object设置的命令,如果您使用*{...}语法,因此如果您的“用户”object 有一个“id”属性,您将绑定它与*{id} .

The way it will work in your current code would be它在您当前代码中的工作方式是

<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>

Edit: Nonetheless, as some people said in the comments, you should either save your full object in bound hidden inputs so you can recover it in the controller (if for some reason you need the full object there), or, since you are really only binding an id, use a String/Integer/whatever as your model attribute instead of an "User" object.编辑:尽管如此,正如某些人在评论中所说,您应该将完整的 object 保存在绑定的隐藏输入中,这样您就可以在 controller 中恢复它(如果由于某种原因您需要完整的 ZA8CFDE6331BD59EB2AC96F8911C4B66),或者,仅绑定 id,使用 String/Integer/whatever 作为 model 属性,而不是“用户”object。

Edit2: You need to pass an "user" attribute if your th:fields use it. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM