Thymeleaf(第九十一二章)本地变量#属性优先级#注释和块#内联

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thymeleaf(第九十一二章)本地变量#属性优先级#注释和块#内联相关的知识,希望对你有一定的参考价值。

9 本地变量

为一个模板的指定片段定义的变量叫做本地变量,只在那个片段里可用。
例如下面这个prod迭代变量:

1<tr th:each="prod : ${prods}">
2...
3</tr>

prod变量只在<tr>标签的界限内可用。特别地:
它将对在这个标签里执行的任何th:*属性都可用,这些属性的优先级要比th:each要低。
它将对任何这个标签的子元素都是可用的,如任何<td>元素。

thymeleaf提供一种方式来声明本地变量,使用th:with属性,它的语法像为属性赋值:

1<div th:with="firstPer=${persons[0]}">
2  <p>
3    The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
4  </p>
5</div>

当th:with被处理时,firstPer变量被创建为一个本地变量,且添加到来自于上下文的变量map里,因此它可以和任何其它定义在上下文里的变量一起计算,但是仅限于在包含它的那个<div>标签的界限内。

可以一次定义多个变量,使用通常的多赋值语法:

1<div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">
2  <p>
3    The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.
4  </p>
5  <p>
6    But the name of the second person is 
7    <span th:text="${secondPer.name}">Marcus Antonius</span>.
8  </p>
9</div>

th:with属性允许在同一个属性里重复使用已定义的变量:

1<div th:with="company=${user.company + ‘ Co.‘},account=${accounts[company]}">...</div>

下面是之前的一个示例:

1<p>
2  Today is: 
3  <span th:text="${#calendars.format(today,‘dd MMMM yyyy‘)}">13 february 2011</span>
4</p>

我们可以把日期格式字符串提取出来放入到消息属性文件里:
如home_en.properties:
date.format=MMMM dd‘‘,‘‘ yyyy
另一个home_es.properties:
date.format=dd ‘‘de‘‘ MMMM‘‘,‘‘ yyyy
现在,让我们使用th:with来获取本地化的日期格式到一个变量里,然后把它用在th:text表达式里:

1<p th:with="df=#{date.format}">
2  Today is: <span th:text="${#calendars.format(today,df)}">13 February 2011</span>
3</p>

这非常清晰和简单。事实上,th:with的优先级比th:text高,我们可以把它们两个都写到<span>标签里:

1<p>
2  Today is: 
3  <span th:with="df=#{date.format}" 
4        th:text="${#calendars.format(today,df)}">13 February 2011</span>
5</p>

10 属性优先级

当你把多个th:*属性写到一个标签里会发生什么?像这样:

1<ul>
2  <li th:each="item : ${items}" th:text="${item.description}">Item description here...</li>
3</ul>

我们希望th:each属性先执行,然后th:text再执行,这样才会产生我们想要的结果。但是html/XML标准并没有给出标签的属性之间的顺序,所以一个优先级机制需要被建立,这样才能按照期望的去工作。

所有的thymeleaf属性都定义了一个数字优先级,这个优先级建立了属性间的执行顺序:

技术图片

优先级机制意味着属性之间的先后位置变得不再重要,只是阅读起来有点不爽:

1<ul>
2  <li th:text="${item.description}" th:each="item : ${items}">Item description here...</li>
3</ul>

11 注释和块

11.1 标准的HTML/XML注释

标准的HTML/XML注释<!-- ... -->可以用在thymeleaf模板里的任何地方,注释里的任何内容都不会被thymeleaf处理,将会一字不差地被拷贝到输出:

1<!-- User info follows -->
2<div th:text="${...}">
3  ...
4</div>

11.2 thymeleaf解析器级别的注释块

解析器级别的注释块,当thymeleaf执行解析时,将简单地从模板中移除。看起来像这样:

1<!--/* This code will be removed at Thymeleaf parsing time! */-->

thymeleaf将移除所有<!--//-->中间的东西。所以当一个模板被静态地打开时,这些注释块能够用来显示代码,当thymeleaf开始处理时,它将被移除:

1<!--/*--> 
2  <div>
3     you can see me only before Thymeleaf processes me!
4  </div>
5<!--*/-->

这可以非常方便地用于原型中的表格里的多行<tr>,例如:

 1<table>
 2   <tr th:each="x : ${xs}">
 3     ...
 4   </tr>
 5   <!--/*-->
 6   <tr>
 7     ...
 8   </tr>
 9   <tr>
10     ...
11   </tr>
12   <!--*/-->
13</table>

11.3 thymeleaf仅原型注释块

当模板被静态地打开时,它是注释,当模板被thymeleaf处理时,它被认为是正常的标记。

1<span>hello!</span>
2<!--/*/
3  <div th:text="${...}">
4    ...
5  </div>
6/*/-->
7<span>goodbye!</span>

thymeleaf的解析系统将简单地移除<!--//和//-->记号,保留它的内容,所以当执行模板时,thymeleaf实际上看到的是这样:

1<span>hello!</span>
2
3  <div th:text="${...}">
4    ...
5  </div>
6
7<span>goodbye!</span>

与解析器级别的注释块相比,这个特性是方言独立的。

11.4 人造的th:block标签

thymeleaf的仅有元素处理器(不是属性)包含在标准的方言中,是th:block。
th:block仅仅是一个属性容器,允许模板开发者来指定他们想要的那些属性。
thymeleaf将执行这些属性,然后简单地使这个块(不是它的内容)消失。

因此它可能有用,例如,当创建迭代表格,且每个元素要求多个<tr>标签时:

 1<table>
 2  <th:block th:each="user : ${users}">
 3    <tr>
 4        <td th:text="${user.login}">...</td>
 5        <td th:text="${user.name}">...</td>
 6    </tr>
 7    <tr>
 8        <td colspan="2" th:text="${user.address}">...</td>
 9    </tr>
10  </th:block>
11</table>

也会特别有用,当和仅原型注释块联合使用时:

 1<table>
 2    <!--/*/ <th:block th:each="user : ${users}"> /*/-->
 3    <tr>
 4        <td th:text="${user.login}">...</td>
 5        <td th:text="${user.name}">...</td>
 6    </tr>
 7    <tr>
 8        <td colspan="2" th:text="${user.address}">...</td>
 9    </tr>
10    <!--/*/ </th:block> /*/-->
11</table>

注意,这种解决方案如何允许模板是一个合法的HTML,同时当直接使用浏览器打开作为原型时也工作正常。

12 内联

12.1 表达式内联

虽然使用标签属性能做几乎所有事情,有些情形我们宁愿把表达式直接写到HTML文本里。我们更倾向于这样写:

1<p>Hello, [[${session.user.name}]]!</p>

而不是这样:

1<p>Hello, <span th:text="${session.user.name}">Sebastian</span>!</p>

[[...]]或[(...)]之间的表达式在thymeleaf里被认为是内联表达式,这些表达式可以是原来用在属性里的合法的任何类型的表达式。
注意,[[...]]对应于th:text,将会进行HTML转义,[(...)]对应于th:utext,将不执行HTML转义。所以对于一个这样的变量msg = ‘This is <b>great!</b>‘,下面这个片段:

1<p>The message is "[(${msg})]"</p>

它的结果是不转义,直接输出:

1<p>The message is "This is <b>great!</b>"</p>

然而,如果要转义的话,就像这样:

1<p>The message is "[[${msg}]]"</p>

结果将被进行HTML转义:

1<p>The message is "This is &lt;b&gt;great!&lt;/b&gt;"</p>

注意,文本内联默认被激活,因此我们不需要开启它。

内联vs自然模板

如果你使用过其它模板引擎,就会觉得这种输出文本的方式是很平常啊,你可能会问,为什么我们不从一开始就这样做?它比所有的那些th:text属性的代码都要少。
好吧,请小心,因为虽然你发现内联十分有趣,你应该总是要记住,当你以静态的方式打开它时,内联表达式将会一字不差地被显式在HTML中,因此你可能不能够再使用它因为设计原型。

当原型中不使用内联时是这样的:

1Hello, Sebastian!

使用内联是这样的:

1Hello, [[${session.user.name}]]!

从设计实用性的角度来讲,它们之间的差别非常明显。

禁用内联

因为有些场合我们想要[[...]]或[(...)]原样输出而不是作为表达式被处理,此时我们将使用th:inline="none":

1<p th:inline="none">A double array looks like this: [[1, 2, 3], [4, 5]]!</p>

这将输出:

1<p>A double array looks like this: [[1, 2, 3], [4, 5]]!</p>

注:还有文本内联、javascript内联、CSS内联,文章不再列出,需要的可自行查阅官方文档。

(完)

以上是关于Thymeleaf(第九十一二章)本地变量#属性优先级#注释和块#内联的主要内容,如果未能解决你的问题,请参考以下文章

目录js测试

#yyds干货盘点# 前端歌谣的刷题之路-第九十一题-继承

“全栈2019”Java第九十二章:外部类与内部类成员覆盖详解

leetcode 简单 第九十一题 找不同

小刘同学的第九十一篇博文

程序设计基础第九十十一章 综合实例分析 递归