thymeleaf 循环_Thymeleaf参考手册(六):迭代

本文介绍了Thymeleaf在前端页面中遍历集合元素的方法,包括th:each的用法、可迭代对象类型,以及迭代状态和惰性加载的概念。通过示例展示了如何在模板中使用th:each,以及如何利用状态变量跟踪迭代状态。
摘要由CSDN通过智能技术生成

6f4b6354413c15b07a622dbf3c5b68d7.png

在前端页面中,总是出现需要遍历集合中的元素以展示所有信息的场景。Thymeleaf标准方言为我们提供了一个有用的属性:th:each

用法

假设后台控制器添加了一个商品列表的属性 prods。然后,我们使用 th:each 在模板中使用来遍历产品列表:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <title>Good Thymes Virtual Grocery</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" media="all" 
          href="../../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
  </head>
  <body>
    <h1>Product list</h1>
  
    <table>
      <tr>
        <th>NAME</th>
        <th>PRICE</th>
        <th>IN STOCK</th>
      </tr>
      <tr th:each="prod : ${prods}">
        <td th:text="${prod.name}">Onions</td>
        <td th:text="${prod.price}">2.41</td>
        <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
      </tr>
    </table>
  
    <p>
      <a href="../home.html" th:href="@{/}">Return to home</a>
    </p>
  </body>
</html>

prod : ${prods} 属性的含义为:循环 ${prods} 属性的每一个元素。${prods} 为被迭代变量,prod 为迭代变量,即当前循环的元素。

需要注意的是,prod 为迭代变量的作用域为 <tr> 元素,可用于其内部标记 <td>

可迭代对象

java.util.List 类并不是Thymeleaf中唯一的可被用于迭代的对象。还有一些其它的可被迭代的集合对象:

  • 任何实现于 java.util.Iterable 的对象
  • 任何实现于 java.util.Enumeration 的对象
  • 任何实现于 java.util.Iterator 的对象,其值将由迭代器返回,而无需在内存中缓存
  • 任何实现于 java.util.Map 的对象,当迭代 Map 对象时,迭代对象则是 java.util.Map.Entry
  • 任何数组
  • 任何包含其对象本身的单值列表

迭代状态

在使用 th:each 时,Thymeleaf提供了一种用于跟踪迭代状态的有用机制:状态变量。

状态变量在 th:each 属性中定义,并且包含以下数据:

  • index 属性,当前的迭代索引,从0开始。
  • count 属性,从1开始的当前迭代索引。
  • size 属性,迭代变量中元素的总数。
  • current 属性,每次迭代的变量。
  • even/odd 布尔属性,当前迭代是偶数还是奇数。
  • first 布尔属性,当前迭代是否是第一个。
  • last 布尔属性,当前迭代是否为最后一个。

示例:

<table>
  <tr>
    <th>NAME</th>
    <th>PRICE</th>
    <th>IN STOCK</th>
  </tr>
  <tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
    <td th:text="${prod.name}">Onions</td>
    <td th:text="${prod.price}">2.41</td>
    <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
  </tr>
</table>

状态变量(本例中为 iterStat)通过在 th:each 属性中迭代变量后写入名称,并以逗号分隔。同样的,其作用域与定义 th:each 属性的代码片段一致。

如果未明确设置状态变量,则Thymeleaf将始终通过在迭代变量名后添加 Stat 后缀来创建:

<table>
  <tr>
    <th>NAME</th>
    <th>PRICE</th>
    <th>IN STOCK</th>
  </tr>
  <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
    <td th:text="${prod.name}">Onions</td>
    <td th:text="${prod.price}">2.41</td>
    <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
  </tr>
</table>

惰性加载

有时候我们想优化数据的检索方式,比如在真正用到这些数据时才检索。

实际上,这可以应用于任何数据,但是考虑到内存中集合可能具有的大小,对于这种情况,检索要迭代的集合是最常见的情况。

为了支持这一特性,Thymeleaf提供了一种延迟加载上下文变量的机制。实现 ILazyContextVariable 接口的上下文变量(很可能是通过扩展其 LazyContextVariable 默认实现)将在执行时解析。例如:

model.addAttribute(
     "users",
     new LazyContextVariable<List<User>>() {
         @Override
         protected List<User> loadValue() {
             return databaseRepository.findAllUsers();
         }
     });

可以在不了解其惰性加载特性的情况下使用此变量,例如:

<ul>
  <li th:each="u : ${users}" th:text="${u.name}">user name</li>
</ul>

但是同时, 如果在以下代码中 condition 计算为 false,则将永远不会初始化(loadValue()方法永远不会调用):

<ul th:if="${condition}">
  <li th:each="u : ${users}" th:text="${u.name}">user name</li>
</ul>

我是银河架构师,十年饮冰,难凉热血,愿历尽千帆,归来仍是少年!

如果文章对您有帮助,请举起您的小手,轻轻【三连】,这将是笔者持续创作的动力源泉。当然,如果文章有错误,或者您有任何的意见或建议,请留言。感谢您的阅读!


文章不定时更新,可微信搜索「银河架构师」,精彩内容,先睹为快!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值