17.1 解耦的逻辑:概念
到目前为止,我们都用通常的模版来构建我们的杂货店——以属性的形式将逻辑插入我们的模版。
但是,Thymeleaf也允许我们从它的模版标记中完全解耦逻辑,允许在HTML
和XML
模版模式下创建完全无逻辑的标记模版
。
大意就是将模版逻辑定义在一个分开的逻辑文件里(更准确地说,是一个逻辑资源,因为可以不是一个文件)。默认地,逻辑资源是一个额外的文件,和模版文件在同一个地方(比如,文件夹)。它们名字相同,但是逻辑资源文件的扩展名是.th.xml
:
/templates
+->/home.html
+->/home.th.xml
因此,home.html
文件可以是完全无逻辑的。看起来就像这样:
<!DOCTYPE html>
<html>
<body>
<table id="usersTable">
<tr>
<td class="username">Jeremy Grapefruit</td>
<td class="usertype">Normal User</td>
</tr>
<tr>
<td class="username">Alice Watermelon</td>
<td class="usertype">Administrator</td>
</tr>
</table>
</body>
</html>
没有任何的Thymeleaf代码。这是一个连没有Thymeleaf或者模板知识的设计者也可以创建、编辑、理解的模板文件。或者,这是一段由某些外部系统提供的没有一点儿Thymeleaf挂钩的HTML。
现在,让我们通过创建额外的home.th.xml
文件,把那个home.html
模板转变为Thymeleaf模板。就像这样:
<?xml version="1.0"?>
<thlogic>
<attr sel="#usersTable" th:remove="all-but-first">
<attr sel="/tr[0]" th:each="user : ${users}">
<attr sel="td.username" th:text="${user.name}" />
<attr sel="td.usertype" th:text="#{|user.type.${user.type}|}" />
</attr>
</attr>
</thlogic>
我们可以在thlogic
块里面看到许多的<attr>
标签。那些<attr>
标签在由sel
属性指定的原始模板的节点上执行属性注入。它们包含Thymeleaf标记选择器(实际上是AttoParser标记选择器)。
也请注意:<attr>
标签可以内嵌,这样它们的选择器可以扩展。比如,上面的sel="/tr[0]"
,会被当做sel="#usersTable/tr[0]"
处理。用于用户名<td>
的选择器会被当做sel="#usersTable/tr[0]//td.username"
处理。
因此,一旦合并,上面看到的两个文件会等同于:
<!DOCTYPE html>
<html>
<body>
<table id="usersTable" th:remove="all-but-first">
<tr th:each="user : ${users}">
<td class="username" th:text="${user.name}">Jeremy Grapefruit</td>
<td class="usertype" th:text="#{|user.type.${user.type}|}">Normal User</td>
</tr>
<tr>
<td class="username">Alice Watermelon</td>
<td class="usertype">Administrator</td>
</tr>
</table>
</body>
</html>
这看起来更为熟悉,比起创建两个独立的文件,也确实更加简单。但是,解耦的模板的优势在于我们能够给予模板完全的自由。因此,从设计的观点来看,有更好的可维护性。
当然,设计者和开发人员之间还是需要某些协议。比如,用户<table>
需要一个id="usersTable"
。但是,在许多的场景下,纯HTML模板更易于设计团队与开发团队之间的交流。