可能是最全的Thymeleaf参考手册(六):迭代

 

在前端页面中,总是出现需要遍历集合中的元素以展示所有信息的场景。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>

 

                                  公众号回复以下关键字,获取更多资源

 

 

SpringCloud进阶之路 | Java 基础 | 微服务 | JAVA WEB | JAVA 进阶 | JAVA 面试 | MK 精讲

 

 

 

 

 

笔者开通了个人微信公众号【银河架构师】,分享工作、生活过程中的心得体会,填坑指南,技术感悟等内容,会比博客提前更新,欢迎订阅。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值