Skip to content

使用th:each实现遍历

要开发产品列表页面,首先需要编写控制器方法:从服务层获取产品列表,并将其添加到模板上下文。

java
public void process(
        final IWebExchange webExchange, 
        final ITemplateEngine templateEngine, 
        final Writer writer)
        throws Exception {
    
    // 1. 从服务层获取所有产品
    final ProductService productService = new ProductService();
    final List<Product> allProducts = productService.findAll();
    
    // 2. 创建模板上下文,将产品列表以 "prods" 为键存入
    final WebContext ctx = new WebContext(webExchange, webExchange.getLocale());
    ctx.setVariable("prods", allProducts);
    
    // 3. 处理模板(product/list),传入上下文并输出结果
    templateEngine.process("product/list", ctx, writer);
    
}

用 th:each 遍历产品列表

html
<!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>
      <!-- th:each 遍历 prods 集合,每次循环将当前元素赋值给 prod 变量 -->
      <tr th:each="prod : ${prods}">
        <td th:text="${prod.name}">Onions</td> <!-- 渲染产品名称 -->
        <td th:text="${prod.price}">2.41</td> <!-- 渲染产品价格 -->
        <!-- 渲染库存状态:根据 inStock 布尔值显示国际化文本 -->
        <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} 表达式的结果(产品列表),对列表中的每个元素,重复渲染这段模板片段,并将当前元素存入名为 prod 的变量中”

我们给这些概念明确命名:

  • ${prods}:称为被遍历表达式/被遍历变量(即要遍历的集合);
  • prod:称为遍历变量/迭代变量(即每次循环代表的当前元素)。

⚠️ 重要注意点: prod 这个遍历变量的作用域仅限于 <tr> 元素——这意味着它只能在 <tr> 内部的标签(如 <td>)中使用,超出这个范围则无法访问。

执行逻辑补充

  • 静态原型表现:直接打开模板文件时,会显示表格表头 + 一行静态数据(Onions、2.41、yes),符合 Thymeleaf “静态原型可预览”的特性;
  • 动态渲染表现:后端处理模板时,<tr th:each="prod : ${prods}"> 会被复制 N 份(N 等于产品列表长度),每份中的 ${prod.name}/${prod.price} 等会替换为对应产品的实际数据;
  • 库存状态渲染:${prod.inStock}? #{true} : #{false} 会根据产品的 inStock 布尔值,读取国际化配置文件中的 true/false 对应的文本(比如中文环境下显示“是/否”)。

总结

  1. 使用 th:each 需先在控制器中将遍历的集合(如产品列表)存入模板上下文(示例中键为 prods);
  2. th:each 核心语法是 遍历变量 : ${被遍历集合},遍历变量仅在当前元素及其子元素内有效;
  3. 遍历过程中可结合 th:text、条件表达式、国际化表达式等,渲染动态数据。