Thymeleaf使用th:each动态创建表单

时间:2019-01-31 17:21:41

标签: java spring thymeleaf

我想知道如何为在th:object中循环的每个对象创建使用th:each的表单。例如,我有以下代码。

HTML

<th:block th:each="store: ${stores}">
    <form th:object="${store}" th:action="@{/modify-store}">
        <input th:field="*{idStorePk}"/>
        <input th:field="*{name}"/>
        <input th:field="*{phoneNumber}"/>
        <button type="submit">Modify</button>
    </form>
</th:block>

控制器

@RequestMapping(value = "/stores")
public String getIndex(Model model) {
    model.addAttribute("stores", storeService.getAllStores());
    return "store";
}

因此,我想为每个对象添加一个表单,但是似乎不可能,并且出现以下错误。

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'store' available as request attribute

因此,我决定在控制器中添加一个@ModelAttribute,但无法返回实际的商店。

@ModelAttribute("store")
public Store getStore(Store store) {
    return store;
}

使用这种方法,我所有的表格都为空值。我也尝试添加一个@PathVariable,但是看不到使用th:object绑定它。有解决方案吗?

2 个答案:

答案 0 :(得分:1)

因此,对于陷入类似问题的任何人。我发现可以帮助您的解决方法。首先,您不能使用th:object,它根本不会削减它。相反,请执行以下操作。

<th:block th:each="store: ${stores}">
    <form class="store-form" th:action="@{/modify-store}">
        <input th:name="idStorePk" th:value="${store.idStorePk}"/>
        <input th:name="name" th:value="${store.name}"/>
        <input th:name="phoneNumber" th:value="${store.phoneNumber}"/>
        <button class="submit-button" type="submit">Modify</button>
    </form>
</th:block>

然后只需添加类似于控制器的内容即可。

@PostMapping(value = "/modify-store")
@ResponseBody
public boolean deleteEntry(@ModelAttribute Store store) throws Exception {
    // Your code here...
    return true;
}

如果要异步发送,则需要添加一些JS代码才能使其正常工作。它看起来应该类似于下面的代码。

const forms = document.querySelectorAll('.store-form');
forms.forEach(form => {
   form.addEventListener('submit', event => {

   // Stop the normal form submit triggered by the submit button
   event.preventDefault();

   const formInputs = form.getElementsByTagName("input");
   let formData = new FormData();
   for (let input of formInputs) {
       formData.append(input.name, input.value);
   }

   fetch(form.action,
   {
        method: form.method,
        body: formData
   })
   .then(response => response.json())
   .then(data => console.log(data))
   .catch(error => console.log(error.message))
   .finally(() => console.log("Done"));
});

答案 1 :(得分:0)

您要在模型属性中的控制器中发送商店,并在正在使用 store 提交表单的第二个控制器中发送商店,这就是您这样做的原因正在收到此错误。因此,请更正您的任何控制器上的拼写错误。像这样:-

@RequestMapping(value = "/stores")
public String getIndex(Model model) {
    model.addAttribute("stores", storeService.getAllStores());
    return "store";
}

提交表单的第二个控制器就是这样-

@ModelAttribute("stores")
public Store getStore(Store store) {
    return store;
}