考虑以下场景:
public class PersonForm {
@NotNull
private String name;
/*usual getters and setters*/
}
@Controller
@SessionAttribute(types={ PersonForm.class })
public class MyController {
@RequestAttribute(...)
public String render(final ModelMap map) {
/* get list of info and for each info
* create a PersonForm and put it in the modelmap
* under key p0, p1, p2, ..., pn
*/
}
public String submit(final ModelMap map,
@Valid final PersonForm form,
final BindingResult result) {
if (result.hasErrors()) {
// return to page
} else {
// do necessary logic and proceed to next page
}
}
}
...
<c:forEach ...>
<form:form commandName="p${counter}">
... other form:elements and submit button goes here
</form:form>
</c:forEach>
...
如您所见,我正在尝试处理同一类类型的多种形式。提交工作——它让我很好地使用了 submit(...) 方法,验证也是如此。但是重新渲染页面并没有向我显示预期的错误消息!
更糟糕的是——我检查了提交 header 中传递的内容,没有任何迹象表明提交了哪个表单,因此无法区分一个表单和另一个表单。这让我相信同一类类型的多种形式是不可能的......
有没有其他方法可以做到这一点(除了 Ajax)?
非常感谢。
最佳答案
我设法让这个“黑客”发挥作用。正如果冻所推荐的那样,这一切都归功于他。
简单来说,这个概念是使用传统的 <c:forEach>
预先填充您的 View 。构造。棘手的部分是每当按下相应行的“提交”按钮时,所有信息都必须注入(inject)隐藏表单并强制提交给 Controller 。如果屏幕再次出现一些错误,则脚本必须负责将值注入(inject)包括错误在内的相应行。
1)我的模型
public class PersonForm {
private String id;
@NotNull
private String name;
/*usual getters and setters*/
}
2)我的 Controller
@Controller
@SessionAttribute(/* the hidden form name, the person list */)
public class MyController {
@RequestAttribute(...)
public String render(final ModelMap map) {
/* get list of info and for each info
* create a PersonForm and put it in the modelmap
* under key p0, p1, p2, ..., pn
*/
}
public String submit(final ModelMap map,
@Valid final PersonForm form,
final BindingResult result) {
if (result.hasErrors()) {
// return to page
} else {
// do necessary logic and proceed to next page
}
}
}
3) 我的看法
...
<form:form commandName="personForm" cssStyle="display: none;">
<form:hidden path="id"/>
<form:hidden path="name" />
<form:errors path="name" cssStyle="display: none;" />
</form:form>
...
<c:forEach var="p" items="${pList}">
<input type="text" id="${ p.id }Name" value="${ p.name }" />
<!-- to be filled in IF the hidden form returns an error for 'name' -->
<span id="${ p.id }nameErrorSpan"></span>
<button type="button" value="Submit" onclick="injectValuesAndForceSubmit('${ p.id }');" />
</c:forEach>
...
<script type="text/javascript">
injectValuesAndForceSubmit = function(id) {
$('#id').val( id ); // fill in the hidden form's id
$('#name').val( $('#'+id+'name').val() ); //fill in the hidden form's name
$('#personForm').submit(); //submit!
}
$(document).ready(function() {
var id = $('#id').val();
if (id.trim().length == 0) {
//Empty. Nothing to do here as this is a simple render.
} else {
//The page seems to be returning from some sort of error ... pre-fill the respective row!
$('#'+id+'name').val($('#name').val());
var hiddenNameErrorSpan = $('#name.errors');
if (hiddenNameErrorSpan) {
$('#'+id+'nameErrorSpan').text(hiddenNameErrorSpan.html());
}
} //else
}
</script>
正如您所看到的,该 View 具有最毛茸茸的部分——希望它仍然对任何(不幸地)遇到与我相同情况的人有用。干杯!
关于spring - 处理同一类型的多种形式 - 不可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11859967/