当用户转到 recipe / new 时,它会发送RecipeCommand对象,然后在用户设置信息后 Recipe Ingredients 和 Directions , RecipeCommand 对象被发送到 recipe / new / ingredients 。我将它转换为配方对象然后保存并返回它。然后我发送一个 Ingredients Wrapper ,它有N个RecipeCommands(取决于用户在Recipe Ingredients设置的数量)和RecipeCommand,然后返回 recipe / recipe_add_ingredients 。这导致 recipe / new / {recipeId} / ingredients / directions 。然后我使用IngredientsWrapper并将每个IngredientCommand对象添加到RecipeCommand。问题是该对象具有空ID,即使我已将其添加到数据库中并且它显示其ID为2.这是代码: add_recipe
<form th:object="${recipe}" th:action="@{/recipe/new/ingredients}" enctype="multipart/form-data">
<input type="hidden" th:field="*{id}">
<div class="add-recipe-container">
<div class="add-recipe-inputs-container">
<div class="add-recipe-inputs">
<ul class="add-recipe-inputs-list">
<li>
<label for="recipeName">Recipe Name </label>
<input id="recipeName" name="recipeName" th:field="*{recipeName}" type="text">
</li>
<li>
<label for="cookTime">Cook Time</label>
<input th:field="*{recipeCookTime}" placeholder="Without minutes" type="number">
</li>
<li>
<label for="prepTime">Prep Time</label>
<input th:field="*{recipePrepTime}" placeholder="Without minutes" type="number">
</li>
<li>
<label for="servings">Servings</label>
<input th:field="*{recipeServings}" type="number">
</li>
</ul>
</div>
</div>
<div class="add-recipe-options-container">
<div class="add-recipe-options">
<ul class="add-recipe-options-list">
<li>
<label>Difficulty</label>
<select th:field="*{difficulty}" id="difficulty.id">
<option th:each="difficultyEach : ${T(com.vio.spring5.domain.Difficulty).values()}"
th:value="${difficultyEach.id}"
th:text="${difficultyEach.name}">
</option>
</select>
</li>
<li>
<label>Category</label>
<select th:field="*{recipeCategory}" id="recipeCategory.id">
<option th:each="category : ${T(com.vio.spring5.domain.RecipeCategory).values()}"
th:value="${category.id}"
th:text="${category.name}">
</option>
</select>
</li>
<li>
<label for="ingredientsAmount">Ingredients</label>
<input th:field="*{recipeIngredientsAmount}" type="number">
</li>
<li>
<label for="directionsAmount">Directions</label>
<input th:field="*{recipeDirectionsAmount}" type="number">
</li>
<li>
<label for="">Image</label>
<input th:field="*{image}" id="imagefile" name="imagefile" type="file" class="file">
</li>
</ul>
</div>
</div>
</div>
<button type="submit" class="next-page-button">Next</button>
</form>
将Add_Ingredient
<form th:object="${ingredientsWrapper}" th:action="@{'/recipe/new/' + ${recipe.getId()} + '/ingredients/directions'}" method="get">
<div class="add-recipe-container">
<ul class="recipe-many">
<li th:each="ingredientInputs, iter : ${ingredientsWrapper.ingredientsWrapperSet}">
<ul class="add-recipe-ingredients-list">
<li>
<label for="">Amount</label>
<input th:field="*{ingredientsWrapper[__${iter.index}__].amount}" type="number">
</li>
<li>
<label for="">Unit</label>
<select th:field="*{ingredientsWrapper[__${iter.index}__].unitOfMeasure}">
<option th:each="unit : ${unitOfMeasure}"
th:value="${unit.id}"
th:text="${unit.unitName}">Test</option>
</select>
</li>
<li>
<label for="">Ingredient Name</label>
<input th:field="*{ingredientsWrapper[__${iter.index}__].ingredientName}" type="text">
</li>
</ul>
</li>
</ul>
</div>
<button type="submit" class="add-recipe">Add Recipe</button>
</form>
add_directions
<form th:object="${directionsWrapper}" th:action="@{'/recipe/new/' + ${recipe.id} + '/ingredients/directions'}" method="post">
<div class="add-directions-container">
<ul class="directions-many">
<li th:each="directions, iter : ${directionsWrapper.directionsWrapperList}">
<label>Step: </label>
<textarea th:field="*{directionsWrapper[__${iter.index}__].directions}" cols="40" rows="3"></textarea>
</li>
</ul>
</div>
<button type="submit" class="add-recipe">Add Recipe</button>
</form>
控制器
/*
* Send a RecipeCommand object to front
*/
@GetMapping(value = "/recipe/new")
public String newRecipe(Model model) {
model.addAttribute("recipe", new RecipeCommand());
return "recipe/recipe_add";
}
/*
* Send the recipe wrapper
* To do: throw exception and validation
*
*/
@GetMapping(value = "/recipe/new/ingredients")
public String addIngredients(@ModelAttribute("recipe") RecipeCommand recipe, BindingResult bidingResult, Model model) {
recipeService.saveRecipeCommand(recipe);
IngredientsWrapper wrapper = new IngredientsWrapper();
addIngredientsCommandObjects(wrapper, recipe.getRecipeIngredientsAmount());
model.addAttribute("unitOfMeasureSet", uomService.findAll());
model.addAttribute("ingredientsWrapper", wrapper);
model.addAttribute("recipe", recipe);
return "recipe/recipe_add_ingredients";
}
/*
* to do: validate
*/
@GetMapping(value = "/recipe/new/{recipeId}/ingredients/directions")
public String addDirections (@PathVariable String recipeId,
@ModelAttribute("ingredientsWrapper") IngredientsWrapper wrapper, Model model) {
RecipeCommand recipe = recipeService.findRecipeCommandById(Long.valueOf(recipeId));
wrapper.ingredientsWrapperSet
.iterator()
.forEachRemaining(ingredient -> recipe.addIngredient(ingredient));
recipeService.updateRecipeCommandIngredients(recipe);
DirectionsWrapper directionsWrapper = new DirectionsWrapper();
addDirectionsCommandObjects(directionsWrapper, recipe.getRecipeDirectionsAmount());
model.addAttribute("directionsWrapper", directionsWrapper);
model.addAttribute("recipe", recipe);
return "recipe/recipe_add_directions";
}
/*
* to do: validate
*/
@PostMapping(value = "/recipe/new/{recipeId}/ingredients/directions/")
public String addRecipe(@PathVariable String recipeId,
@ModelAttribute("directionsWrapper") DirectionsWrapper wrapper) {
RecipeCommand recipe = recipeService.findRecipeCommandById(Long.valueOf(recipeId));
wrapper.directionsWrapperList
.iterator()
.forEachRemaining(directions -> recipe.addDirections(directions));
recipeService.updateRecipeCommandDirections(recipe);
return "redirect:/browse";
}