【问题标题】:How to filter last entries with JSP c:forEach and c:if?如何使用 JSP c:forEach 和 c:if 过滤最后一个条目?
【发布时间】:2013-04-28 12:26:03
【问题描述】:

我正在尝试使用 JSP 页面开发 Spring MVC 应用程序,但遇到了问题。这更像是一个创造力问题而不是代码问题,但这里是:

因此,应用程序基本上会收到一个配方(字段名称、问题描述、问题解决方案等)并在创建时为其添加一个 ID。

我想要在首页显示最后创建的 3 个食谱。我想出了一个代码,显然显示了 first 3 个创建的食谱:

<c:forEach var="recipe" items='${recipes}'>
    <c:if test="${recipe.id < 4}
        <div class="span4">
            <h3<c:out value="${recipe.inputDescProb}"></c:out></h3>
            <p><c:out value="${recipe.inputDescSol}"></c:out></p>
            <p><a class="btn" href="/recipes/${recipe.id}">Details &raquo</a></p>
        </div>
    </c:if>
</c:forEach>

关于如何显示最后创建的 3 个食谱有什么想法吗?

【问题讨论】:

  • 您这样做是因为您正在使用 ajax 或类似的东西(再一次)检索收据列表吗?
  • 不,不使用 ajax。目前它仅通过本地地图进行本地化,没有持久性。

标签: java jsp spring-mvc jstl


【解决方案1】:

使用fn:length() EL 函数计算配方总数。在我们使用任何EL function 之前,我们还需要导入必要的tag library

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

然后我们使用&lt;c:set&gt; 将总数设置为页面范围的属性。

<c:set var="totalRecipes" value="${fn:length(recipes)}" />

&lt;c:forEach&gt; 允许您使用其varStatus 属性获取循环计数器。计数器的范围是循环本地的,它会自动为您递增。这个loop counter 从 1 开始计数。

<c:forEach var="recipe" items='${recipes}' varStatus="recipeCounter">
  <c:if test="${recipeCounter.count > (totalRecipes - 3)}">
    <div class="span4">
      <h3<c:out value="${recipe.inputDescProb}"></c:out></h3>
      <p><c:out value="${recipe.inputDescSol}"></c:out></p>
      <p><a class="btn" href="/recipes/${recipe.id}">Details &raquo;</a></p>
    </div>
  </c:if>
</c:forEach>

编辑:使用LoopTagStatus 类的count 属性以${varStatusVar.count} 访问EL 中迭代计数器的当前值。

【讨论】:

  • 很好的解释,我只是接触了这些 JSTL 方法的基础,我明白了它是如何工作的。我仍然收到错误消息。当我加载没有条目的页面时,它加载正常。但是当我输入 1 个或多个食谱并返回主页时,我得到了这个:Cannot convert javax.servlet.jsp.jstl.core.LoopTagSupport$1Status@ffed1d of type class javax.servlet.jsp.jstl.core.LoopTagSupport$1Status to class java.lang.Long 我猜问题出在 For 循环上?
  • 使用 count 属性并将括号放在 ${recipeCounter.count > (totalRecipes - 3)} 以避免运算符优先级副作用。
【解决方案2】:

无需检查长度,只需使用varStatus 变量的.last 属性即可。

<c:forEach var="recipe" items="${recipes}" varStatus="status">
  <c:if test="${not status.last}">
    Last Item
  </c:if>
<c:forEach>

旁注,您还可以获得.first.count

【讨论】:

    【解决方案3】:

    您可以使用${fn:length(recipes)} 将当前计数与总集合大小进行比较:

    <c:set var="total" value="${fn:length(recipes)}"/>
    
    
    <c:forEach var="recipe" items='${recipes}' varStatus="status">
      <c:if test="${status.count > total - 3}">
        <div class="span4">
          <h3<c:out value="${recipe.inputDescProb}"></c:out></h3>
          <p><c:out value="${recipe.inputDescSol}"></c:out></p>
          <p><a class="btn" href="/recipes/${recipe.id}">Details &raquo</a></p>
        </div>
      </c:if>
    </c:forEach>
    

    编辑:

    您需要先导入 fn 以使 JSTL fn 可供使用:

    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    

    【讨论】:

    • 我试过了,我得到了 /WEB-INF/jsp/home.jsp(31,30) PWC6287: The attribute prefix fn does not correspond to any imported tag library 第 30 行:&lt;div class="row"&gt;(没关系)和第 31 行:&lt;c:set var="total" value="${fn:length(recipes)}" varStatus="count"/&gt; 我必须导入什么才能让它工作?
    • varStatus 属性使用不正确。它应该在c:forEach&gt; 中使用。详情参考我的回答。
    • 好的,我导入了 JSTL 函数,但我仍然得到 PWC6131: Attribute varStatus invalid for tag set according to TLD 指的是 &lt;c:set var="total" value="${fn:length(recipes)}" varStatus="count"/&gt; (我认为上面的评论总结了 - 如果可以的话,正确的用法是什么?)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 2014-03-06
    • 2015-07-20
    • 2023-03-18
    相关资源
    最近更新 更多