【问题标题】:Spring MVC - Thymeleaf form binding with an arraylistSpring MVC - Thymeleaf 表单与数组列表绑定
【发布时间】:2018-03-13 14:06:36
【问题描述】:

在特定视图中,我确实有一个可扩展的员工列表。每个员工有 2 个字段,它们是 hoursWorkedadvancePayments。只需单击 1 次按钮,我想发布整个表单。为了实现这一点,我向包含多个 POJO(基于员工数量)的视图发送了一个列表。

添加到列表中的 POJO 如下所示:

@Setter
@Getter
@NoArgsConstructor
public class WorkdayCommand {

    private Long employeeId;
    private Integer hoursWorked;
    private Integer advancePayment;
}

在控制器中,我确实有一行可以将列表添加到模型中:

model.addAttribute("workdayCommands", employeeService.getListOfWorkdayCommandsWithIds());

以及形成实际列表的方法:

public List<WorkdayCommand> getListOfWorkdayCommandsWithIds(){

    List<WorkdayCommand> listOfCommands = new ArrayList<>();
    List<Long> listOfIds = employeeRepository.getListOfIds();

    for(int i = 0; i < employeeRepository.getNumberOfEmployees(); i++){

        WorkdayCommand workdayCommand = new WorkdayCommand();
        workdayCommand.setEmployeeId(listOfIds.get(i));
        listOfCommands.add(workdayCommand);
    }

    return listOfCommands;
}

现在,我的观点有问题:

<div class="table-responsive" th:if="${not #lists.isEmpty(employees)}">
    <form th:object="${workdayCommands}" th:action="@{/addworkday}">
         some table headers...
         <tr th:each="employee : ${employees}">
              <td><a href="#" role="button" th:href="@{'/employee/' + ${employee.id}}" th:text="${employee.name}">Mike Kowalsky</a></td>
              <td><input type="text" class="form-control" placeholder="Enter hours" th:field="*{hoursWorked}"></td>
              <td><input type="text" class="form-control" placeholder="Enter payment" th:field="*{advancePayment}"></td>
              <td><input type="hidden" th:field="*{id}"/></td>
         </tr>
    </form>
</div>

到目前为止,我一直收到错误:

NotReadablePropertyException: Invalid property 'hoursWorked' of bean class [java.util.ArrayList]: Bean property 'hoursWorked' is not readable or has an invalid getter method

如何正确绑定数组列表和视图?我想问题是数组列表中没有hoursWorked这样的字段。我应该使用什么th:field 参数来获取实际的WorkdayCommand.hoursWorked 字段,然后遍历列表以获取所有员工?如果您需要更多信息,请随时询问。

我正在尝试这样的事情:

th:field="*{[__${iter.index}__].hoursWorked}"

...但这仍然行不通。我与列表中的第一个 POJO 无关。

编辑 2

我的完整视图如下所示:

在单个表格行中,我确实有一些员工信息以及 2 个输入和 2 个按钮。每一行的创建归功于:

 <tr th:each="employee : ${employees}">

点击提交按钮时,会创建一个新的 Workday 对象,然后将其持久化到数据库中。发生这种情况时,工作日需要与相应的员工相关联。所以我的:

 <tr th:each="employee : ${employees}">

...我还分配了一个隐藏的id 字段。然后我们有WorkdayCommand,它从视图中收集所有信息。所以employeeId 字段是我将工作日与相应员工相关联的方式。它应该使用为每个显示所有信息传递的id 值。希望现在清楚了。

【问题讨论】:

  • 您还应该在workdayCommands 上进行迭代,就像在employees 上一样
  • 关于我在哪里做的任何线索?在form 标签中?

标签: java spring spring-mvc thymeleaf


【解决方案1】:

您不能直接绑定到ArrayList 作为th:object。相反,您应该创建一个具有 ArrayList 作为属性的对象。

@Setter
@Getter
@NoArgsConstructor
public class WorkdayForm {
    private List<WorkdayCommand> workdayCommands = new ArrayList<>();
}

然后你循环遍历,像这样绑定它们:

<form th:object="${workdayForm}" th:action="@{/addworkday}">
  <!-- table headers -->
  <tr th:each="workdayCommand, i : ${workdayForm.workdayCommand}">
      <td><input type="text" class="form-control" placeholder="Enter hours" th:field="*{workdayCommands[__${i.index}__].hoursWorked}"></td>
      <td><input type="text" class="form-control" placeholder="Enter payment" th:field="*{workdayCommands[__${i.index}__].advancePayment}"></td>
      <td><input type="hidden" th:field="*{workdayCommands[__${i.index}__].employeeId}"/></td>
  </tr>
  <!-- table footers -->
</form>

【讨论】:

  • 好的。这是合理的。还有1个问题。首先,在遍历员工时,隐藏字段id 被赋值。需要将相同的值传递给支持对象中的employeeId 字段。这样,我可以肯定,时间和付款分配给正确的员工。我不能在单个表格行中包含 2 个th:each...关于如何解决这个问题的任何线索?
  • 我不确定你的意思...workCommand 上的employeeId 是什么?为什么需要遍历员工?
  • workdayCommand 应该有一个员工作为它的属性,然后...作为循环的一部分,您可以像这样显示员工信息:&lt;td&gt;&lt;a href="#" role="button" th:href="@{'/employee/' + ${employee.id}}" th:text="${workdayCommand.employee.name}"&gt;Mike Kowalsky&lt;/a&gt;&lt;/td&gt;
  • 或者,您可以只遍历员工而不是工作日命令。据我所知,一切都会保持不变。
猜你喜欢
  • 2023-03-25
  • 2015-02-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 2019-10-19
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多