Post 如何为Thymeleaf中的多个对象填写一个表单中的字段?
我有以下模型(没有可读性的getter和setter): * 我需要做的是在一个Thymeleaf表单中填写每个对象的字段并发布它。我知道如何用一个物体来做。请解释如何为多个对象设置from和controller,以便最终将配方与配料和说明列表一起发布。谢谢 编辑: 以下是一个控制器方法:Post 如何为Thymeleaf中的多个对象填写一个表单中的字段?,post,spring-boot,view,controller,thymeleaf,Post,Spring Boot,View,Controller,Thymeleaf,我有以下模型(没有可读性的getter和setter): * 我需要做的是在一个Thymeleaf表单中填写每个对象的字段并发布它。我知道如何用一个物体来做。请解释如何为多个对象设置from和controller,以便最终将配方与配料和说明列表一起发布。谢谢 编辑: 以下是一个控制器方法: @RequestMapping("/recipes/add") public String formNewRecipe(Model model) { Recipe recipe = ne
@RequestMapping("/recipes/add")
public String formNewRecipe(Model model) {
Recipe recipe = new Recipe();
if (!model.containsAttribute("recipe")) {
model.addAttribute("recipe", recipe);
}
model.addAttribute("action", "/recipes");
model.addAttribute("heading", "New Recipe");
model.addAttribute("submit", "Save");
model.addAttribute("categories", Category.values());
model.addAttribute("measurements", Measurement.values());
return "edit";
}
@RequestMapping(value = "/recipes", method = RequestMethod.POST)
public String addRecipe(@Valid Recipe recipe,
BindingResult result,
RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
redirectAttributes
.addFlashAttribute("org.springframework.validation.BindingResult.recipe", result);
redirectAttributes.addFlashAttribute("recipe", recipe);
return "redirect:/recipes/add";
}
recipes.save(recipe);
redirectAttributes.addFlashAttribute("flash",
new FlashMessage("New Recipe Created!!!", FlashMessage.Status.SUCCESS));
return "redirect:/recipes/" + recipe.getId();
}
及百里香表格:
<form th:action="@{${action}}" method="post" th:object="${recipe}">
<div class="grid-100 row controls">
<div class="grid-50">
<h2 th:text="${heading}"></h2>
</div>
<div class="grid-50">
<div class="flush-right">
<input class="button" type="submit" th:value="${submit}"/>
<a th:href="@{|/recipes|}" class="secondary">
<button class="secondary">Cancel</button>
</a>
</div>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Name </label>
</p>
</div>
<div class="grid-40">
<p><input type="text" th:field="*{name}"/>
<div class="error-message"
th:if="${#fields.hasErrors('name')}"
th:errors="*{recipe.name}">
</div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Description </label>
</p>
</div>
<div class="grid-40">
<p><textarea rows="4" th:field="*{description}"></textarea>
<div class="error-message"
th:if="${#fields.hasErrors('description')}"
th:errors="*{recipe.description}">
</div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Category </label>
</p>
</div>
<div class="grid-30">
<p>
<select th:field="*{category}">
<option value="" disabled="disabled">Recipe Category</option>
<option th:each="c : ${categories}"
th:value="${c.name}"
th:text="${c.name}">All Categories</option>
</select>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Prep Time </label>
</p>
</div>
<div class="grid-20">
<p>
<input type="number" th:field="*{preparationTime}"/>
<div class="error-message"
th:if="${#fields.hasErrors('preparationTime')}"
th:errors="*{preparationTime}"></div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Cook Time </label>
</p>
</div>
<div class="grid-20">
<p>
<input type="number" th:field="*{cookTime}"/>
<div class="error-message"
th:if="${#fields.hasErrors('cookTime')}"
th:errors="*{cookTime}"></div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Ingredients </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Item </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Condition </label>
</p>
</div>
<div class="grid-15">
<p class="label-spacing">
<label> Quantity </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Measurement </label>
</p>
</div>
<div class="ingredient-row">
<div class="prefix-20 grid-20">
<p>
<input type="text" th:field="*{ingredients[0].name}"/>
<div class="error-message"
th:if="${#fields.hasErrors('ingredients[0].name')}"
th:errors="*{ingredients[0].name}"></div>
</p>
</div>
<div class="grid-20">
<p>
<input type="text" th:field="*{ingredients[0].condition}"/>
<div class="error-message"
th:if="${#fields.hasErrors('ingredients[0].condition')}"
th:errors="*{ingredients[0].condition}"></div>
</p>
</div>
<div class="grid-15">
<p>
<input type="number" th:field="*{ingredients[0].quantity}"/>
<div class="error-message"
th:if="${#fields.hasErrors('ingredients[0].quantity')}"
th:errors="*{ingredients[0].quantity}"></div>
</p>
</div>
<div class="grid-20">
<p>
<select th:field="*{ingredients[0].measurement}">
<option value="" disabled="disabled">Measurement</option>
<option th:each="i : ${measurements}"
th:value="${i.name}"
th:text="${i.name}">Unknown
</option>
</select>
</p>
</div>
</div>
<div class="prefix-20 grid-80 add-row">
<p>
<button>+ Add Another Ingredient</button>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Instructions </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Steps </label>
</p>
</div>
<div class="grid-60">
<p class="label-spacing">
<label> Description </label>
</p>
</div>
<div class="instruction-row">
<div class="prefix-20 grid-20">
<p>
<input type="text" th:field="*{instructions[0].name}"/>
<div class="error-message"
th:if="${#fields.hasErrors('instructions[0].name')}"
th:errors="*{instructions[0].name}"></div>
</p>
</div>
</div>
<div class="instruction-row">
<div class="grid-50">
<p>
<input type="text" th:field="*{instructions[0].description}"/>
<div class="error-message"
th:if="${#fields.hasErrors('instructions[0].description')}"
th:errors="*{instructions[0].description}"></div>
</p>
</div>
</div>
<div class="prefix-20 grid-80 add-row">
<p>
<button>+ Add Another Step</button>
</p>
</div>
</div>
<div class="clear"></div>
<div class="row"> </div>
</form>
名称
描述
类别
配方类别
所有类别
准备时间
烹饪时间
成分
项目
条件
量
测量
测量
不为人知
+添加另一种成分
说明书
台阶
描述
+添加另一个步骤
它看起来像这样:
<form th:object="${recipe}">
<input type="text" th:field="*{ingredients[0].name}" />
<input type="text" th:field="*{ingredients[0].description}" />
<input type="text" th:field="*{instructions[1].name}" />
<input type="text" th:field="*{instructions[1].description}" />
</form>
<th:block th:each="ingredient,i : ${recipe.ingredients}">
<input type="text" th:field="*{ingredients[__${i.index}__].name}" /><br />
<input type="text" th:field="*{ingredients[__${i.index}__].condition}" /><br />
<input type="text" th:field="*{ingredients[__${i.index}__].quantity}" /><br />
<input type="text" th:field="*{ingredients[__${i.index}__].measurement.anotherField}" /><br />
</th:block>
在表单中动态添加另一个成分有点痛苦。。。您必须提交表单并在控制器中修改配方对象(添加配料,然后重定向)
<form th:action="@{${action}}" method="post" th:object="${recipe}">
<div class="grid-100 row controls">
<div class="grid-50">
<h2 th:text="${heading}"></h2>
</div>
<div class="grid-50">
<div class="flush-right">
<input class="button" type="submit" th:value="${submit}"/>
<a th:href="@{|/recipes|}" class="secondary">
<button class="secondary">Cancel</button>
</a>
</div>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Name </label>
</p>
</div>
<div class="grid-40">
<p><input type="text" th:field="*{name}"/>
<div class="error-message"
th:if="${#fields.hasErrors('name')}"
th:errors="*{recipe.name}">
</div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Description </label>
</p>
</div>
<div class="grid-40">
<p><textarea rows="4" th:field="*{description}"></textarea>
<div class="error-message"
th:if="${#fields.hasErrors('description')}"
th:errors="*{recipe.description}">
</div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Category </label>
</p>
</div>
<div class="grid-30">
<p>
<select th:field="*{category}">
<option value="" disabled="disabled">Recipe Category</option>
<option th:each="c : ${categories}"
th:value="${c.name}"
th:text="${c.name}">All Categories</option>
</select>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Prep Time </label>
</p>
</div>
<div class="grid-20">
<p>
<input type="number" th:field="*{preparationTime}"/>
<div class="error-message"
th:if="${#fields.hasErrors('preparationTime')}"
th:errors="*{preparationTime}"></div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Cook Time </label>
</p>
</div>
<div class="grid-20">
<p>
<input type="number" th:field="*{cookTime}"/>
<div class="error-message"
th:if="${#fields.hasErrors('cookTime')}"
th:errors="*{cookTime}"></div>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Ingredients </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Item </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Condition </label>
</p>
</div>
<div class="grid-15">
<p class="label-spacing">
<label> Quantity </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Measurement </label>
</p>
</div>
<div class="ingredient-row">
<div class="prefix-20 grid-20">
<p>
<input type="text" th:field="*{ingredients[0].name}"/>
<div class="error-message"
th:if="${#fields.hasErrors('ingredients[0].name')}"
th:errors="*{ingredients[0].name}"></div>
</p>
</div>
<div class="grid-20">
<p>
<input type="text" th:field="*{ingredients[0].condition}"/>
<div class="error-message"
th:if="${#fields.hasErrors('ingredients[0].condition')}"
th:errors="*{ingredients[0].condition}"></div>
</p>
</div>
<div class="grid-15">
<p>
<input type="number" th:field="*{ingredients[0].quantity}"/>
<div class="error-message"
th:if="${#fields.hasErrors('ingredients[0].quantity')}"
th:errors="*{ingredients[0].quantity}"></div>
</p>
</div>
<div class="grid-20">
<p>
<select th:field="*{ingredients[0].measurement}">
<option value="" disabled="disabled">Measurement</option>
<option th:each="i : ${measurements}"
th:value="${i.name}"
th:text="${i.name}">Unknown
</option>
</select>
</p>
</div>
</div>
<div class="prefix-20 grid-80 add-row">
<p>
<button>+ Add Another Ingredient</button>
</p>
</div>
</div>
<div class="clear"></div>
<div class="grid-100 row">
<div class="grid-20">
<p class="label-spacing">
<label> Instructions </label>
</p>
</div>
<div class="grid-20">
<p class="label-spacing">
<label> Steps </label>
</p>
</div>
<div class="grid-60">
<p class="label-spacing">
<label> Description </label>
</p>
</div>
<div class="instruction-row">
<div class="prefix-20 grid-20">
<p>
<input type="text" th:field="*{instructions[0].name}"/>
<div class="error-message"
th:if="${#fields.hasErrors('instructions[0].name')}"
th:errors="*{instructions[0].name}"></div>
</p>
</div>
</div>
<div class="instruction-row">
<div class="grid-50">
<p>
<input type="text" th:field="*{instructions[0].description}"/>
<div class="error-message"
th:if="${#fields.hasErrors('instructions[0].description')}"
th:errors="*{instructions[0].description}"></div>
</p>
</div>
</div>
<div class="prefix-20 grid-80 add-row">
<p>
<button>+ Add Another Step</button>
</p>
</div>
</div>
<div class="clear"></div>
<div class="row"> </div>
</form>
<form th:object="${recipe}">
<input type="text" th:field="*{ingredients[0].name}" />
<input type="text" th:field="*{ingredients[0].description}" />
<input type="text" th:field="*{instructions[1].name}" />
<input type="text" th:field="*{instructions[1].description}" />
</form>
<th:block th:each="ingredient,i : ${recipe.ingredients}">
<input type="text" th:field="*{ingredients[__${i.index}__].name}" /><br />
<input type="text" th:field="*{ingredients[__${i.index}__].condition}" /><br />
<input type="text" th:field="*{ingredients[__${i.index}__].quantity}" /><br />
<input type="text" th:field="*{ingredients[__${i.index}__].measurement.anotherField}" /><br />
</th:block>