您不能Set
在 MVC 中用作绑定目标,因为无法为其项目创建属性路径。
你应该使用什么
您应该Map<Integer, YourType>
在构建动态表单时使用。我们已经实施了很多次(所以我知道它正在工作)是这样的:
- 一个简单的数字序列用作键,与实际项目没有任何联系
- 键序列总是在增加,但不需要是连续的(例如,如果用户删除第二个项目,你最终会得到
1, 3, 4, ...
)
- 如果你想添加另一个项目,你只需找到最高的数字,然后添加索引的表单
maxIndex + 1
(总是增加顺序)
Map
实现必须是的实例,以便保留迭代顺序(如果需要自动填充字段LinkedHashMap
,Spring 默认创建此实现)Map
- 必须是某些父表单对象的
Map
一部分(即您不能将其Map
作为顶级表单对象),以便 Spring 能够从属性 getter 中推断出泛型类型
视图和 JavaScript 实现示例
有很多方法可以使用它。例如我们有一个特殊的模板子表单,当我们需要动态添加另一个子表单时使用它。这种方法可能更复杂一些:
<form:form action="${formUrl}" method="post" modelAttribute="organizationUsersForm">
<%-- ... other fields ... --%>
<div id="userSubforms">
<c:forEach items="${organizationUsersForm.users.entrySet()}" var="subformEntry">
<div data-subform-key="${subformEntry.key}">
<spring:nestedPath path="users['${subformEntry.key}']">
<%@ include file="user-subform.jspf" %>
</spring:nestedPath>
</div>
</c:forEach>
</div>
<button onclick="addSubform(jQuery('#userSubforms'), 'users', 'user', 'userTemplate');">ADD ANOTHER USER</button>
<%-- other form fields, submit, etc. --%>
</form:form>
<div class="hide" data-subform-template="user">
<spring:nestedPath path="userTemplate">
<%@ include file="user-subform.jspf" %>
</spring:nestedPath>
</div>
<script>
function addSubform(subformContainer, subformPath, templateName, templatePath) {
// Find the sequence number for the new subform
var existingSubforms = subformContainer.find("[data-subform-key]");
var subformIndex = (existingSubforms.length != 0) ?
parseInt(existingSubforms.last().attr("data-subform-key"), 10) + 1 : 0;
// Create new subform based on the template
var subform = jQuery('<div data-subform-key="' + subformIndex + '" />').
append(jQuery("[data-subform-template=" + templateName + "]").children().clone(true));
// Don't forget to update field names, identifiers and label targets
subform.find("[name]").each(function(node) {
this.name = subformPath + "["+ subformIndex +"]." + this.name;
});
subform.find("[for^=" + templatePath + "]").each(function(node) {
this.htmlFor = this.htmlFor.replace(templatePath + ".", subformPath + "["+ subformIndex +"].");
});
subform.find("[id^=" + templatePath + "]").each(function(node) {
this.id = this.id.replace(templatePath + ".", subformPath + "["+ subformIndex +"].");
});
// Add the new subform to the form
subformContainer.append(subform);
}
</script>
现在您可以问“用户如何删除子表单”?如果子表单 JSPF 包含以下内容,这很容易:
<button onclick="jQuery(this).parents('[data-subform-key]').remove();">DELETE USER</button>