ThymeLeaf-将表数据(ArrayList)发布到另一个控制器

时间:2019-06-10 18:35:15

标签: spring thymeleaf

我很难绑定Thymeleaf POST中的ObjectList。

我正在尝试使用Spring 5和ThymeLeaf达到以下要求

1. User uploads a Excel File
2. Display data in HTML Table (For Java Script Data Validation)
3. Allow User to Delete Invalid Rows  (from Inmemory User Specific ArrayList)
4. Display Remaining Values
5. POST valid remaining values to Server

我打算在每行中添加一个删除按钮。还有一个“提交”按钮,用于将所有剩余的行保存在数据库中。

如何将每个行列表转发到另一个控制器(用于删除操作和数据库保存)。

@PostMapping("/load-excel")
public ModelAndView loadFile(@RequestParam("fileName") MultipartFile file,
         @RequestParam("selectedApplicationName") String selectedApplicationName,RedirectAttributes redirectAttr,Model model) {

        List<EachRowinExcel> eachRowList = fileReaderService.convertExceltoObjList();
        ....

        modelAndView.addObject("eachRowList", eachRowList);

        return modelAndView;
}



 <tr th:each="eachRow : ${eachRowList}">
              <td th:text="${eachRow.column1}"></td>
              <td th:text="${eachRow.column2}"></td>
              <td th:text="${eachRow.column3}"></td>
              <td th:text="${eachRow.column4}"></td>
              <td th:text="${eachRow.column5}"></td>
              <td th:text="${eachRow.column6}"></td>
              <td th:text="${eachRow.column7}"></td>
              <!-- Special Columns -->
              <th:block th:each="customColumnValue:${eachRow.customColumnsList}">
                <td th:text="${customColumnValue}"></td>
              </th:block> 

            </tr>

更新1:

修改后的视图

<form action="#" th:action="@{/access/delete}" th:object="${form}" method="post">
    <table id="accessRequestDataTable"  class="display compact" style="width:100%">
      <thead>
        <tr>
          <!-- Headers -->       
        </tr>
      </thead>
      <tbody>
     <tr th:each="eachRow, iter : ${form.eachRowList}">
          <td  th:text="${eachRow.accessReqeustCounter}" th:field="*{eachRowList[__${iter.index}__].accessReqeustCounter}"></td>
          <td  th:text="${eachRow.accessReqeustID}" th:field="*{eachRowList[__${iter.index}__].accessReqeustID}"></td>
          <td  th:text="${eachRow.accessRequestType}" th:field="*{eachRowList[__${iter.index}__].accessRequestType}"></td>
          <td  th:text="${eachRow.userProfile}" th:field="*{eachRowList[__${iter.index}__].userProfile}"></td>
          <td  th:text="${eachRow.userFinalName}" th:field="*{eachRowList[__${iter.index}__].userFinalName}"></td>
          <td  th:text="${eachRow.userLoginName}" th:field="*{eachRowList[__${iter.index}__].userLoginName}"></td>
          <td  th:text="${eachRow.userEmail}" th:field="*{eachRowList[__${iter.index}__].userEmail}"></td>

          <td>              
            <button class="btn btn-danger btn-sm" 
            type="submit" value="submit">Delete</button>             
          </td>
        </tr>        

      </tbody>
    </table>
  </form>

POST控制器

@RequestMapping(value = "/access/delete", method = RequestMethod.POST)
public ModelAndView deleteUserFromTable(@ModelAttribute("form") EachRowListWrapper eachRowListWrapper){
    System.out.println(eachRowListWrapper.getEachRowList().size());
    ModelAndView modelAndView = new ModelAndView();
    eachRowListWrapper.getEachRowList().remove(0);
    modelAndView.setViewName("access-table");
    return modelAndView;        
}

更新2

对列标题采用了类似的方法。包装类中有另一个List对象。 它在初始加载时有效,但是从POST控制器返回后,标头丢失了。

  <thead>
    <tr>              
      <th scope="col">User Name</th>
      <th scope="col">Login</th>
      <th scope="col">Email</th>
      <th:block th:each="key, iter : ${form.customColumns}">
        <th th:text="${key}" scope="col"></th>
        <input type="hidden" th:field="${form.customColumns[__${iter.index}__]}" />
      </th:block> 
      <th scope="col">Action</th>
    </tr>
  </thead>

最终更新:

显然,th:field输入标记将不会绑定在thead部分内(它不应该具有输入字段LoL)。在表启动之前将其移动后,一切都会按预期进行。

2 个答案:

答案 0 :(得分:1)

对于您的提交按钮,您需要一个围绕表格的表格。可能有效的解决方案是使隐藏的输入字段包含每个 td 的数据。

<input type="hidden" th:field="${eachRow.column1}"/>

提交表单后,您可以访问控制器中输入字段保存的数据并将其保存在数据库中。

答案 1 :(得分:1)

您需要将表放入表单中,该表单将确定将在th:object字段中发送给控制器的内容。在春天被称为命令对象。在此示例中,假设您的“ eachRowList”列表位于名为“ form”的命令对象内。

<form method="post"
        th:action="@{/mappingInYourController}"
        th:object="${form}">
<!-- Here goes your table -->
</form>

还必须指定将哪些数据放置在您在th:object中定义的对象内,以便可以将其发送到控制器。可以通过以下方式使用输入th:fields来完成此操作(一个示例中有一行):

<tr th:each="eachRow, iter : ${form.eachRowList}">
<!-- ... -->
<td> <input th:value="${eachRow.column1}" th:field="*{eachRowList[__${iter.index}__].column1}"/>
</td>

请注意,当您使用* {}访问属性时,您是在定义为表单的th:object的内部引用属性。

现在,例如,如果您使用按钮提交表单,则控制器将能够接收其中包含eachRowList列表的命令对象“ form”,并且列表的元素将是表输入中的元素。如果您不希望此输入在表中内联可编辑,则可以使用以下方法做到这一点:

th:readonly="true"