深色模式
14.1 订单列表页
我们先从创建订单列表页面 /WEB-INF/templates/order/list.html 开始:
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>Order list</h1>
<table>
<tr>
<th>DATE</th>
<th>CUSTOMER</th>
<th>TOTAL</th>
<th></th>
</tr>
<tr th:each="o : ${orders}" th:class="${oStat.odd}? 'odd'">
<td th:text="${#calendars.format(o.date,'dd/MMM/yyyy')}">13 jan 2011</td>
<td th:text="${o.customer.name}">Frederic Tomato</td>
<td th:text="${#aggregates.sum(o.orderLines.{purchasePrice * amount})}">23.32</td>
<td>
<a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a>
</td>
</tr>
</table>
<p>
<a href="../home.html" th:href="@{/}">Return to home</a>
</p>
</body>
</html>这段代码里的内容基本都符合预期,只有这行 OGNL 表达式的写法稍显特别:
html
<td th:text="${#aggregates.sum(o.orderLines.{purchasePrice * amount})}">23.32</td>它的执行逻辑是:
- 遍历当前订单(
o)中的每一条订单项(OrderLine对象); - 对每个订单项,调用其
getPurchasePrice()和getAmount()方法获取purchasePrice(采购单价)和amount(数量)属性,并计算两者的乘积; - 将所有订单项的乘积结果收集为一个数值列表;
- 最后通过
#aggregates.sum(...)工具函数对这个列表求和,得到该订单的总金额。
不得不说,OGNL 的功能确实强大。
关键补充说明
th:each="o : ${orders}":遍历后端传入的orders订单列表,o代表当前遍历的订单对象;${oStat.odd}? 'odd':oStat是遍历的状态对象,odd属性判断当前是否为奇数行,若是则添加odd样式类;#calendars.format(...):Thymeleaf 内置的日期格式化工具,将订单日期按dd/MMM/yyyy格式展示;@{/order/details(orderId=${o.id})}:Thymeleaf 的 URL 链接表达式,动态生成带订单 ID 参数的详情页链接;o.orderLines.{purchasePrice * amount}:OGNL 的投影语法,作用是从集合中提取指定计算结果并生成新列表。
总结
- 订单列表页面通过 Thymeleaf 完成了订单数据的遍历、日期格式化、动态链接生成等核心功能;
- OGNL 投影语法(
{})可快速遍历集合并计算属性值,结合#aggregates.sum()能便捷实现订单金额求和; - Thymeleaf 的内置工具类(如
#calendars、#aggregates)和表达式语法,大幅简化了页面数据渲染的逻辑。
