【问题标题】:JSTL Iterate over list creating fieldsetsJSTL 遍历列表创建字段集
【发布时间】:2012-02-13 16:13:46
【问题描述】:

大家好,我目前正在遍历一个列表,并根据它们是否符合特定条件对字段集进行硬编码。如何编写一个循环来创建基于lidst 中所有组名的字段集,并使用与该组名一起动态出现的所有相应显示名称填充该字段集。我目前对此进行硬编码。

<%@ include file="../include/pre-header.html" %>

    <tr>
        <th>
            <span onclick="toggleDiv('displayFields', 'displayImg')" style="cursor: hand;">Data Fields&nbsp;<img name="displayImg" src="../images/minus.gif" /></span>
        </th>

    </tr>

    <tr>
        <td>

            <div id="displayFields" style="display:block;">
            <fieldset class="det">
                <legend>Header Data</legend>
                    <c:forEach var="detBean" items="${detFields}">
                        <c:if test="${detBean.groupName == 'HEADER_DATA'}">
                    <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                            <br/>
                        </c:if>
                   </c:forEach>
            </fieldset>

            <fieldset class="det">
                <legend>Materiel Data</legend>
                    <c:forEach var="detBean" items="${detFields}">
                        <c:if test="${detBean.groupName == 'MATERIEL_DATA'}">
                    <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                            <br/>
                        </c:if>
                    </c:forEach>
            </fieldset>

            <fieldset class="det">
                <legend>Planned Unit Data</legend>
                    <c:forEach var="detBean" items="${detFields}">
                        <c:if test="${detBean.groupName == 'PLANNED_DATA'}">
                    <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                            <br/>
                        </c:if>
                    </c:forEach>
            </fieldset>

            <fieldset class="det">
                <legend>Actual Unit Data</legend>
                    <c:forEach var="detBean" items="${detFields}">
                        <c:if test="${detBean.groupName == 'ACTUAL_DATA'}">
                <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                            <br/>
                        </c:if>
                </c:forEach>
            </fieldset>

            <fieldset class="det">
                <legend>Planned Cost Data</legend>
                <c:forEach var="detBean" items="${detFields}">
                    <c:if test="${detBean.groupName == 'COST_DATA'}">
                        <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                        <br/>
                    </c:if>
                </c:forEach>
            </fieldset>

            <fieldset class="det">
                <legend>Carry Over Data</legend>
                    <c:forEach var="detBean" items="${detFields}">
                        <c:if test="${detBean.groupName == 'CARRYOVER_DATA'}">
                    <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                        <br/>
                        </c:if>
                    </c:forEach>
            </fieldset>

            <fieldset class="det">
                <legend>Schedule Exceptions</legend>
                    <c:forEach var="detBean" items="${detFields}">
                        <c:if test="${detBean.groupName == 'SCHEDULE_EXCEPTIONS'}">
                    <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                        <br/>
                        </c:if>
                    </c:forEach>
            </fieldset>

            <fieldset class="det">
                <legend>DIFMS data</legend>
                    <c:forEach var="detBean" items="${detFields}">
                        <c:if test="${detBean.groupName == 'DIFMS_DATA'}">
                    <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                        <br/>
                        </c:if>
                    </c:forEach>
            </fieldset>
            </div>
            <tr>
            <td style="text-align: center;">
            <input type="button" name="clear_choice"  value="Check All" onclick="checkUncheck(true);"/>
            &nbsp;&nbsp;&nbsp;&nbsp;
            <input type="button" name="clear_choice"  value="Uncheck All" onclick="checkUncheck(false);"/>

            </td>
            </tr>

        </td>
        </tr>

【问题讨论】:

    标签: jsp jstl


    【解决方案1】:

    我建议将您的数据结构从 List&lt;DetBean&gt; 更改为 Map&lt;String, List&lt;DetBean&gt;&gt;,其中组名是映射键。

    下面的例子展示了如何转换它:

    Map<String, List<DetBean>> detFieldMap = new LinkedHashMap<String, List<DetBean>>();
    
    for (DetBean detBean : detFields) {
        String groupName = detBean.getGroupName();
        List<DetBean> detBeans = detFieldMap.get(groupName);
    
        if (detBeans == null) {
            detBeans = new ArrayList<DetBean>();
            detFieldMap.put(groupName, detBeans);
        }
    
        detBeans.add(detBean);
    }
    
    request.setAttribute("detFieldMap", detFieldMap);
    

    (您当然也可以在创建原始detFields 列表时更改数据结构)

    您可能还想维护所有标题名称的映射

    Map<String, String> detFieldHeaders = new HashMap<String, String>();
    detFieldHeaderMap.put("HEADER_DATA", "Header Data");
    detFieldHeaderMap.put("MATERIEL_DATA", "Materiel Data");
    // ...
    
    request.setAttribute("detFieldHeaders", detFieldHeaders);
    

    (最好在 webapp 启动时创建一次并存储在应用程序范围内,您可以为此使用 ServletContextListener

    这样您就可以使用单个嵌套的&lt;c:forEach&gt;。对 Map 的每次迭代都会返回 Map.Entry ,而后者又具有 getKey()getValue() 方法。键是String 组名,值是List&lt;DetBean&gt;

    <c:forEach items="${detFieldMap}" var="detFieldEntry">
        <fieldset class="det">
            <legend>${detFieldHeaders[detFieldEntry.key]}</legend>
            <c:forEach items="${detFieldEntry.value}" var="detBean">
                <input type="checkbox" name="fieldNames" value="${detBean.fieldName}">${detBean.displayName}</input>
                <br/>
            </c:forEach>
        </fieldset>
    </c:forEach>
    

    【讨论】:

    • 这看起来有点光滑 BalusC.. 我正要试一试
    • Hel BalusC.因为你非常了解我在做什么。如果我想迭代并按较大组 fieldSets 的顺序显示到最小怎么办。这意味着每个组都附加了 x 个显示名称。如果我想在迭代时将具有最多 fieldName 的组放在列表的开头怎么办?
    • 这是可能的,但这会变得很棘手,因为可排序的地图默认情况下是按键排序的,而不是按值排序的。您需要创建一个HashMap,然后在完成后创建另一个TreeMap,并使用您围绕已经创建的HashMap 构建的Comparator&lt;Entry&lt;String, List&lt;DetBean&gt;&gt;&gt;
    • 这就是我的想法。我为您创建的第一个哈希图创建了一个哈希图...并且不担心` Map detFieldHeaders ' ...只是更改了数据库中的 groupNames
    • 我记得曾经在[java] 中发布过类似的答案,但现在找不到。让我看看... 编辑:啊,找到了类似的答案,在这里检查createSortedMap() 方法stackoverflow.com/questions/8855849/… 这有点不同,使用Comparable,但它应该提供一些见解。
    猜你喜欢
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    相关资源
    最近更新 更多