17.1 解耦的逻辑:概念

到目前为止,我们都用通常的模版来构建我们的杂货店——以属性的形式将逻辑插入我们的模版。

但是,Thymeleaf也允许我们从它的模版标记中完全解耦逻辑,允许在HTMLXML模版模式下创建完全无逻辑的标记模版

大意就是将模版逻辑定义在一个分开的逻辑文件里(更准确地说,是一个逻辑资源,因为可以不是一个文件)。默认地,逻辑资源是一个额外的文件,和模版文件在同一个地方(比如,文件夹)。它们名字相同,但是逻辑资源文件的扩展名是.th.xml

  1. /templates
  2. +->/home.html
  3. +->/home.th.xml

因此,home.html文件可以是完全无逻辑的。看起来就像这样:

  1. <!DOCTYPE html>
  2. <html>
  3. <body>
  4. <table id="usersTable">
  5. <tr>
  6. <td class="username">Jeremy Grapefruit</td>
  7. <td class="usertype">Normal User</td>
  8. </tr>
  9. <tr>
  10. <td class="username">Alice Watermelon</td>
  11. <td class="usertype">Administrator</td>
  12. </tr>
  13. </table>
  14. </body>
  15. </html>

没有任何的Thymeleaf代码。这是一个连没有Thymeleaf或者模板知识的设计者也可以创建、编辑、理解的模板文件。或者,这是一段由某些外部系统提供的没有一点儿Thymeleaf挂钩的HTML。

现在,让我们通过创建额外的home.th.xml文件,把那个home.html模板转变为Thymeleaf模板。就像这样:

  1. <?xml version="1.0"?>
  2. <thlogic>
  3. <attr sel="#usersTable" th:remove="all-but-first">
  4. <attr sel="/tr[0]" th:each="user : ${users}">
  5. <attr sel="td.username" th:text="${user.name}" />
  6. <attr sel="td.usertype" th:text="#{|user.type.${user.type}|}" />
  7. </attr>
  8. </attr>
  9. </thlogic>

我们可以在thlogic块里面看到许多的<attr>标签。那些<attr>标签在由sel属性指定的原始模板的节点上执行属性注入。它们包含Thymeleaf标记选择器(实际上是AttoParser标记选择器)。

也请注意:<attr>标签可以内嵌,这样它们的选择器可以扩展。比如,上面的sel="/tr[0]",会被当做sel="#usersTable/tr[0]"处理。用于用户名<td>的选择器会被当做sel="#usersTable/tr[0]//td.username"处理。

因此,一旦合并,上面看到的两个文件会等同于:

  1. <!DOCTYPE html>
  2. <html>
  3. <body>
  4. <table id="usersTable" th:remove="all-but-first">
  5. <tr th:each="user : ${users}">
  6. <td class="username" th:text="${user.name}">Jeremy Grapefruit</td>
  7. <td class="usertype" th:text="#{|user.type.${user.type}|}">Normal User</td>
  8. </tr>
  9. <tr>
  10. <td class="username">Alice Watermelon</td>
  11. <td class="usertype">Administrator</td>
  12. </tr>
  13. </table>
  14. </body>
  15. </html>

这看起来更为熟悉,比起创建两个独立的文件,也确实更加简单。但是,解耦的模板的优势在于我们能够给予模板完全的自由。因此,从设计的观点来看,有更好的可维护性。

当然,设计者和开发人员之间还是需要某些协议。比如,用户<table>需要一个id="usersTable"。但是,在许多的场景下,纯HTML模板更易于设计团队与开发团队之间的交流。