如何使用Thymeleaf和JQuery绑定动态子列表并正常提交表单数据?
问题根因
你动态生成的产品行对应的input输入框没有设置符合Spring MVC参数绑定规则的name属性,后端无法将这些输入框的值映射到RecipeEntity的products列表中,因此收到的列表为空。
解决方案
1. 补全实体类的JPA关联注解(必做,否则数据入库会失败)
你当前的实体类没有声明一对多关联关系,就算参数提交成功也无法正常存入数据库,修改如下:
Recipe实体类
@Entity @Table(name = "recipes") public class RecipeEntity extends BaseEntity { private String name; private String shortDescription; private String cookingInstructions; private Integer cookingTime; private Integer portions; // 新增关联注解,mappedBy对应ProductEntity里的recipe属性 @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true) private List<ProductEntity> products = new ArrayList<>(); // 初始化列表,避免绑定失败 //GETTERS, SETTERS }
Product实体类
@Entity @Table(name = "products") public class ProductEntity extends BaseEntity { private String name; private Double quantity; // 新增多对一注解,关联recipe主键 @ManyToOne @JoinColumn(name = "recipe_id", nullable = false) private RecipeEntity recipe; //GETTERS, SETTERS }
2. 修正jQuery动态添加行的逻辑
新增行时要先计算当前已有产品的数量,作为新行的索引,给两个input设置正确的name属性:
$(document).ready(function () { $('.add-product').click(function () { // 计算当前已有的产品行数,作为新行的索引 let currentIndex = $('.product.row').length; let newRow = jQuery('<div class="product row">' + ' <div class="col-lg-6 mb-3">' + ' Name' + ` <input type="text" name="products[${currentIndex}].name" class="form-control form-control-lg"/>` + ' </div>' + ' <div class="col-lg-6 mb-3">' + ' Quantity(grams)' + ` <input type="number" step="0.1" min="0" name="products[${currentIndex}].quantity"` + ' class="form-control form-control-lg"/>' + '</div>' + '</div>'); $('.products').append(newRow); }); });
补充说明
如果你的Controller层是用@ModelAttribute接收RecipeEntity对象,做完以上修改后提交表单,就能正常拿到完整的products列表,级联存入数据库。
内容的提问来源于stack exchange,提问作者codingmonkey
相关产品推荐
相关产品推荐

