【问题标题】:Is it possible to POST one specific item from a List using Thymeleaf?是否可以使用 Thymeleaf 从列表中发布一个特定项目?
【发布时间】:2019-02-03 09:13:08
【问题描述】:

在我的 Spring Boot 应用程序中,我有以下 RequestMapping

@GetMapping("/test")
public String get(Model model) {
    List<CustomItem> items = itemService.findAll();
    model.addAttribute("items", items);
    return "test";
}

我在一个简单的 HTML 表格中显示这些项目(一个项目一行)。

我想为每一行添加一个按钮,该按钮仅将相应的CustomItem 提交到类似这样的端点:

@PostMapping("/test")
public String post(CustomItem item) {
    // doing something with item
    return "redirect:/test";
}

我尝试的是为每一行创建一个单独的form

<table>
 <tr th:each="item, stat : ${items}">
  <td>
   <form th:object="${items[__${stat.index}__]}" th:action="@{/test}" method="post">
    <input type="text" th:field="${items[__${stat.index}__].someField}">
    <button type="submit">Submit</button>
   </form>
  </td>
 </tr>
</table>

但我在导航到页面时收到以下错误:

Bean 名称“items[0]”的 BindingResult 和普通目标对象都不是 可用作请求属性

我也尝试了以下方法:

<table>
 <tr th:each="item, stat : ${items}">
  <td>
   <form th:object="${item}" th:action="@{/test}" method="post">
    <input type="text" th:field="*{someField}">
    <button type="submit">Submit</button>
   </form>
  </td>
 </tr>
</table>

在这种情况下,错误如下:

Bean 名称“item”的 BindingResult 和普通目标对象都不是 可用作请求属性

我无法弄清楚我的方法有什么问题,所以我非常感谢任何建议。

编辑:

正如@StefanEmanuelsson 建议的那样,我尝试省略th:object 属性:

<table>
 <tr th:each="item, stat : ${items}">
  <td>
   <form th:action="@{/test}" method="post">
    <input type="text" th:field="${items[__${stat.index}__].someField}">
    <button type="submit">Submit</button>
   </form>
  </td>
 </tr>
</table>

这样页面加载得很好,但是在提交表单时,控制器中收到的(?)CustomItem 中的someField 的值是null

【问题讨论】:

  • The thymeleaf docs 说:>“表单标签中 th:object 属性的值必须是变量表达式 (${...}),仅指定模型属性的名称,没有属性导航。这意味着像 ${seedStarter} 这样的表达式是有效的,但 ${seedStarter.data} 不是。”我猜您的代码有资格作为属性导航,因为您将迭代变量用作 th:object?我会尝试使用 th:field="${item.someField}" 而不是 th:object.
  • @StefanEmanuelsson 感谢您的回复,请检查我问题末尾的编辑。

标签: java spring spring-mvc thymeleaf


【解决方案1】:

这对我有用:

在控制器中实例化项目并设置为模型:

@GetMapping("/test")
public String get(Model model) {
    List<CustomItem> items = itemService.findAll();
    model.addAttribute("items", items);
    model.addAttribute("item", new CustomItem());
    return "test";
}

HTML:

<table>
        <tr th:each="i : ${items}">
            <form th:action="@{/test}" method="post" th:object="${item}">

                <td th:text="${i.id}" />
                <td th:text="${i.name}" />
            <td><input type="hidden" th:value="${i.id}" name="id" />
                <input type="hidden" th:value="${i.someField}" name="someField" />
                <button type="submit" name="action" value="remove">OK</button></td>
            </form>
        </tr>
    </table>

并在控制器中创建一个方法来处理该项目:

@PostMapping("/test")
    public String test(@ModelAttribute CustomItem item,HttpServletRequest request) {
        doStuff(item);
    }

【讨论】:

    【解决方案2】:

    我已经设法通过简单地使用th:valuename 属性而不是th:field 来解决这个问题:

    <table>
     <tr th:each="item : ${items}">
      <td>
       <form th:action="@{/test}" method="post">
        <input type="text" th:value="${item.someField}" name="someField">
        <button type="submit">Submit</button>
       </form>
      </td>
     </tr>
    </table>
    

    【讨论】:

      猜你喜欢
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 2010-11-06
      • 2021-10-09
      • 1970-01-01
      相关资源
      最近更新 更多