内联 JavaScript 允许在 HTML 模板模式下处理的模板中更好地集成 JavaScript 的 <script> 标签。
与内联文本一样,这实际上相当于在 JAVASCRIPT 模板模式下将脚本内容当作模板来处理,因此文本(TEXT)模板模式的所有功能都将触手可及。然而,在本节中,我们将重点讨论,如何使用它将 Thymeleaf 表达式的输出添加到我们的 JavaScript 块中。
注意,此模式必须使用 th:inline="javascript" 显式启用:
<script th:inline="javascript"> ... var username = [[${session.user.name}]]; ... </script>
这将导致如下输出:
<script th:inline="javascript"> ... var username = "Sebastian \"Fruity\" Applejuice"; ... </script>
在上面的代码中,有两件重要的事情需要注意。
首先,内联 JavaScript 不仅会输出所需的文本,而且还会用引号将其括起来,并对其内容进行 JavaScript 转义,这样表达式的结果就会作为一个格式良好的 JavaScript 字面内容输出。
其次,这种情况的发生是因为我们在输出 ${session.user.name} 表达式时进行了转义,也就是使用了双括号表达式 [[${session.user.name}]]。如果我们使用非转义表达式,比如。
<script th:inline="javascript"> ... var username = [(${session.user.name})]; ... </script>
输出结果如下:
<script th:inline="javascript"> ... var username = Sebastian "Fruity" Applejuice; ... </script>
…这是错误的 JavaScript 代码。但是,如果我们通过附加内联表达式来构建脚本的一部分,那么输出一些未转义的内容可能是我们所需要的,所以这个工具有时还是需要的。
所提到的 JavaScript 内联机制的智能性远远超过了应用 JavaScript 特定的转义和将表达式的结果输出为有效的字面符号。
例如,我们可以用 JavaScript 注释来包装我们的(转义的)内联表达式,比如。
<script th:inline="javascript"> ... var username = /*[[${session.user.name}]]*/ "Gertrud Kiwifruit"; ... </script>
Thymeleaf 将忽略我们在注释之后和分号之前所写的所有内容(在本例中为 'Gertrud Kiwifruit'),因此执行此语句的结果将与不使用包装注释时完全相同:
<script th:inline="javascript"> ... var username = "Sebastian \"Fruity\" Applejuice"; ... </script>
但是再仔细看看原始模板代码:
<script th:inline="javascript"> ... var username = /*[[${session.user.name}]]*/ "Gertrud Kiwifruit"; ... </script>
请注意,这是一段有效的 JavaScript 代码。当您以静态方式打开模板文件时(无需在服务器上执行),它将完美地执行。变量 username 的值为 “Gertrud Kiwifruit
”。
因此,我们这里有了一种来制作 JavaScript 自然模板的方法!
关于 JavaScript 内联需要注意的一件重要事情是,该表达式计算是智能的,并且不限于字符串。Thymeleaf 将正确地用 JavaScript 语法编写以下类型的对象:
Strings 字符串类型
Numbers 数字类型
Booleans 布尔类型
Arrays 数组类型
Collections 集合类型
Maps Ma类型
Beans(对象拥有 getter 和 setter 方法)
例如,如果我们有以下代码:
<script th:inline="javascript"> ... var user = /*[[${session.user}]]*/ null; ... </script>
该 ${ession.user} 表达式的计算结果为 User 对象,而 Thymeleaf 将正确地将其转换为 JavaScript 语法:
<script th:inline="javascript"> ... var user = {"age":null,"firstName":"John","lastName":"Apricot", "name":"John Apricot","nationality":"Antarctica"}; ... </script>
完成此 JavaScript 序列化的方式是通过 org.thymeleaf.standard.serializer.IStandardJavaScriptSerializer 接口的实现,该接口可以在模板引擎使用的 StandardDialect 实例中进行配置。
该 JS 序列化机制的默认实现将在类路径中查找 Jackson 库,如果存在,将使用它。如果不存在,它将应用一种内置的序列化机制,该机制可以满足大多数场景的需求,并产生类似的结果(但灵活性较低)。