2

有没有类似AutoPopulatingList的东西Set?我要显示的数据是一个使用Set.

public class Employer implements java.io.Serializable {
     private Set<Employee> employees = new HashSet();
}

我尝试过使用AutoPopulatingList,但在这种情况下,我必须List在休眠中使用,这需要我指定list-index使用Employee.employeeId,并且每当我稍后检索到时employeesEmployee列表将在元素(元素)之间有空格,null具体取决于Employee.employeeId.

我需要自动填充集合,因为我需要employees在创建Employer. 当我使用 plain 时,我得到以下信息Setorg.springframework.beans.InvalidPropertyException: Invalid property 'employees[0]' of bean class [model.Employer]: Cannot get element with index 0 from Set of size 0, accessed using property path 'employees[0]'

还有其他解决方案吗?

编辑

我正在尝试实现动态表单

4

3 回答 3

4

您不能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>
于 2013-06-09T06:47:56.500 回答
1

Set 不是索引集合,您只能绑定索引集合或数组。您可以尝试使用 LinkedHashSet (那个有保证的顺序,而 HashSet 没有)或使用 List 实现来绑定值。

于 2016-11-08T08:59:56.517 回答
0

“无法获取索引为 0 的元素”.. 集合不是基于开始索引的..

你为什么不使用 LazyList of Employee..正如@PavelHoral 正确指出的那样,我们不需要在 Spring 处理它时使用 LazyList.. 一个简单的 List 初始化(如 new ArrayList())就可以了,尽管有可能当用户提交非连续元素时有空格(空值)。

private List<Employee> employees = new ArrayList<Employee>();
于 2013-06-08T20:22:56.067 回答