【问题标题】:Thymeleaf th:field pre-processing is not working with th:eachThymeleaf th:field 预处理不适用于 th:each
【发布时间】:2020-03-17 14:31:16
【问题描述】:

我想在表格中显示对象列表以及更新字段marketallcoation 的选项。我为此目的使用百里香叶。因此,我不得不将th:eachth:field 中可用的预处理能力结合使用。

在我的控制器类中,我设置了如下所示的属性:

model.addAttribute("marketList",supplyAllocationService.getItems());

在我的 html 页面中,我做了这样的事情:

<table>
<tr th:each="market,iteration : *{marketList}">
                <td><span th:text="${market.date}" th:field="*{marketList[__${iteration.index}__].date}"> Date </span></td>
                <td><span th:text="${market.country}" th:field="*{marketList[__${iteration.index}__].country}"> Country </span></td>
                <td><span th:text="${market.product}" th:field="*{marketList[__${iteration.index}__].product}"> Product </span></td>
                <td><span th:text="${market.sku != null} ? ${market.sku} : 'None'" th:field="*{marketList[__${iteration.index}__].sku}"> SKU </span></td>
                <td><span th:text="${market.aggregateddemand}" th:field="*{marketList[__${iteration.index}__].aggregateddemand}"> Aggregated Demand </span></td>
                <td><span th:text="${market.aggsupply_12}" th:field="*{marketList[__${iteration.index}__].aggsupply_12}"> 12 weeks aggregated supply </span></td>
                <td><input type="text" th:value="${market.marketallcoation}" th:field="*{marketList[__${iteration.index}__].marketallcoation}"/></td>
                <td><span th:text="${market.unmetdemand}"  th:field="*{marketList[__${iteration.index}__].unmetdemand}"> Unmet demand quantity </span></td>
                <td><span th:text="${market.demandplanner}" th:field="*{marketList[__${iteration.index}__].demandplanner}"> Demand Planner </span></td>
                <td><span th:text="${market.bdmcontact}" th:field="*{marketList[__${iteration.index}__].bdmcontact}"> BDM contact </span></td>
                <td></td>
            </tr>
</table>

当我运行代码时,我收到以下错误:

Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'marketList[0]' available as request attribute
    at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903) ~[spring-webmvc-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
    at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]

根据docs,如果使用预处理功能,则不需要th:object。我没有使用它,所以我不确定我在这里缺少什么。

【问题讨论】:

    标签: java spring spring-boot thymeleaf


    【解决方案1】:
    1. 如果您使用*{...} 语法和/或th:field 属性,那么您必须使用th:object(它们都依赖于th:object 才能起作用)。
    2. 您不应该在&lt;span/&gt; 元素上使用th:field——这没有任何意义。 (th:field 设置元素的nameidvalue 属性。namevalue 不影响&lt;span /&gt;s。)

    另外,不幸的是,我认为您不能将List 用作表单对象。因此,要修复您的表单,您需要首先创建一个具有 marketList 作为其属性之一的新对象,然后将其添加到模型中。将该新对象设为表单的th:object,然后预处理应该适合您。

    <form th:object="${yourNewObject}>
      <table>
        <tr th:each="market, iteration: *{marketList}">
          <td th:text="${market.date}" />
          <td th:text="${market.country}" />
          <td th:text="${market.product}" />
          <td th:text="${market.sku != null} ? ${market.sku} : 'None'" />
          <td th:text="${market.aggregateddemand}" />
          <td th:text="${market.aggsupply_12}" />
          <td><input type="text" th:field="*{marketList[__${iteration.index}__].marketallcoation}"/></td>
          <td th:text="${market.unmetdemand}" />
          <td th:text="${market.demandplanner}" />
          <td th:text="${market.bdmcontact}" />
          <td></td>
        </tr>
      </table>
    </form>
    

    【讨论】:

    • 感谢您的回复。我们可以在不使用隐藏元素的情况下使用表单提交来更新和持久化market 对象吗?
    • 我已接受您的回答,因为它在帖子中回答了我的问题。但是,我确实有一个问题:“如何在单击提交按钮时提交特定的market 对象?”。现在,我必须提交整个列表,遍历每个对象并更新值。
    • 是的,如果您在控制器上使用@SessionAttributes 设置模型对象,您可以在不使用隐藏元素的情况下做到这一点——这将为单个表单调用保留已设置的信息。至于你的第二个问题。是的,您可以这样做,但如果您这样做,为什么要将所有市场对象都放在一个表单上?在这种情况下,您可能无法使用th:field,您必须使用th:nameth:value 手动创建表单。
    猜你喜欢
    • 1970-01-01
    • 2018-01-07
    • 2018-05-09
    • 2015-06-17
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    相关资源
    最近更新 更多