Struts 1.3中如何仅迭代表格特定属性A一次?
解决JSP表格中属性A合并单元格显示的问题
这种分组合并单元格的需求我之前也碰到过,直接在迭代里判断加rowspan容易踩布局错乱的坑——核心问题是你没提前把数据按A属性分组,导致rowspan的数值不准确,或者后续行多渲染了A的单元格,破坏了表格的列结构。给你一套靠谱的解决方案:
第一步:后端提前分组数据
首先在Java层(比如Controller或者Service)把原有的tableList按A属性分组,这样能准确知道每个A值对应的行数,避免前端计算错误。示例代码如下:
// 假设你的实体类是YourEntity,包含getA()、getB()、getC()方法 List<YourEntity> tableList = ...; // 原列表 Map<String, List<YourEntity>> groupedByA = new HashMap<>(); // 按A属性分组 for (YourEntity entity : tableList) { String aValue = entity.getA(); // 如果当前A值不存在于Map中,就新建一个列表;否则直接添加实体 groupedByA.computeIfAbsent(aValue, k -> new ArrayList<>()).add(entity); } // 把分组后的数据放到request域中,供JSP调用 request.setAttribute("groupedByA", groupedByA);
第二步:JSP嵌套迭代渲染表格
前端用嵌套的<logic:iterate>标签,外层遍历分组后的A值,内层遍历该A对应的所有B、C属性。只有每个分组的第一行渲染A的单元格,并设置rowspan为该分组的行数,后续行不渲染A的单元格,保证表格列数一致:
<tbody> <%-- 外层遍历每个A分组 --%> <logic:iterate id="group" name="groupedByA" scope="request"> <% // 获取当前分组的A值和对应的子列表 String currentA = (String) group.getKey(); List<YourEntity> subList = (List<YourEntity>) group.getValue(); %> <%-- 内层遍历该A对应的所有实体 --%> <logic:iterate id="e" name="subList" indexId="itemIndex"> <tr> <%-- 只有分组的第一个元素才渲染A的单元格,并设置rowspan --%> <logic:equal name="itemIndex" value="0"> <td rowspan="<%= subList.size() %>"><%= currentA %></td> </logic:equal> <%-- 正常渲染B和C属性 --%> <td><%= e.getB() %></td> <td><%= e.getC() %></td> </tr> </logic:iterate> </logic:iterate> </tbody>
为什么之前的方法会错乱?
你之前直接在Java类中判断A属性值并设置rowspan="12",大概率是因为没有准确统计当前A值对应的总行数,或者后续行仍然渲染了A的单元格,导致表格的列数不一致(比如有的行3列,有的行4列),浏览器无法正确解析表格结构,从而出现布局错乱。
额外注意事项
- 如果A属性是自定义对象,记得重写
equals()和hashCode()方法,否则HashMap无法正确分组。 - 如果你习惯用JSTL标签代替Struts的
logic标签,也可以用<c:forEach>实现,逻辑完全一致,代码会更简洁:
<tbody> <c:forEach items="${groupedByA}" var="group"> <c:forEach items="${group.value}" var="e" varStatus="status"> <tr> <c:if test="${status.first}"> <td rowspan="${group.value.size()}">${group.key}</td> </c:if> <td>${e.B}</td> <td>${e.C}</td> </tr> </c:forEach> </c:forEach> </tbody>
- 确保分组后的子列表不为空,避免出现
rowspan="0"的情况,这会导致单元格不显示。
内容的提问来源于stack exchange,提问作者Kondziowsky
相关产品推荐
相关产品推荐

