我有一个对象,我想动态加载表单字段。实例化和显示字段在显示时正常工作,但是,当我尝试提交表单时,除了用户提供的${field.value}
之外,所有数据都将丢失。如何保留所有其他属性值?
这是生成表单对象的控制器方法:
@RequestMapping(method = RequestMethod.GET)
public String newFooForm(@AuthenticationPrincipal UserDetails user, @RequestParam("fooType") String fooType, @RequestParam("isTeam") Boolean isTeam, Model model) {
Employee currentUser = getCurrentUser(user);
List<FooFieldDefinition> fooFieldDefinitions = fooFieldDefinitionService.findByOrganizationalUnitIdAndIsTeam(currentUser.getOrgId(), isTeam);
FooViewModel fooViewModel = new FooViewModel(currentUser, fooType, isTeam, fooFieldDefinitions);
model.addAttribute("fooViewModel", fooViewModel);
return "newFooForm";
}
在构造函数FooViewModel(currentUser, fooType, isTeam, fooFieldDefinitions)
中调用以下代码段,其中填充了fooViewModel.fooFields:
fooFields = new ArrayList<>();
for (FooFieldDefinition fooFieldDefinition : fooFieldDefinitions) {
fooFields.add(new FooField(fooFieldDefinition));
}
以下是表单的片段:
<form id="foo-form" action="#" th:action="@{/fooForms}" th:object="${fooViewModel}"
method="post">
<div th:each="fooField,iterationStatus : *{fooFields}">
<label th:text="${fooField.label}">Label</label>
<input th:type="text" th:field="*{fooFields[__${iterationStatus.index}__].value}"/>
</div>
<div style="position: absolute; right: 20px; bottom: 20px;">
<input class="btn btn-primary" id="save" type="submit" name="save" value="Save"/>
<input class="btn btn-primary" id="submit" type="submit" name="submit" value="Submit"/>
</div>
</form>
我知道fooField在生成表单时有与该实例关联的相应数据,原因有两个。 label
打印,通过调试,我可以看到实例在newFooForm
方法返回视图名称之前具有相应的数据。
每当我提交表单时,除了从表单传递的值外,每个fooField
的所有数据都设置为null。我知道这是因为,1。数据没有保留,2。调试显示。这是用于提交提交的控制器方法:
@RequestMapping(method = RequestMethod.POST, params = {"save"})
public String fooFormDraftSubmit(@AuthenticationPrincipal UserDetails user, @ModelAttribute FooViewModel fooViewModel, Model model) {
Employee currentUser = getCurrentUser(user);
Foo foo = new Foo(currentUser, fooViewModel);
fooService.save(foo);
for (FooField fooField : fooViewModel.getFooFields()) {
fooFieldService.save(fooField);
}
FooViewModel persistedFooViewModel = new FooViewModel(foo);
model.addAttribute("fooViewModel", persistedFooViewModel);
return "fooView";
}
感谢您的任何建议!
答案 0 :(得分:1)
由于这篇文章我想出了这个:Spring MVC 3 Command Object values being lost between GET and POST operation。具体建议是使用隐藏字段。您必须访问在页面上呈现的ViewModel
的属性值,并将其分配给您希望传递到ViewModel
端点的POST
。
<form id="foo-form" action="#" th:action="@{/fooForms}" th:object="${fooViewModel}"
method="post">
<div th:each="fooField,iterationStatus : *{fooFields}">
<label th:text="${fooField.label}">Label</label>
<input th:type="text" th:field="*{fooFields[__${iterationStatus.index}__].value}"/>
<!-- The fix, this is an example of 1 attribute. Of course I will extend this for appropriate attribute values -->
<input th:type="hidden" th:field="*{fooFields[__${iterationStatus.index}__].label}" th:value="${fooViewModel.fooFields[__${iterationStatus.index}__].label}"/>
<!-- End new code -->
</div>
<div style="position: absolute; right: 20px; bottom: 20px;">
<input class="btn btn-primary" id="save" type="submit" name="save" value="Save"/>
<input class="btn btn-primary" id="submit" type="submit" name="submit" value="Submit"/>
</div>
</form>