本文将说明在Thymeleaf中,如何在标记中设置、或修改属性值的方法。
设置任何属性的值
假设有以下模板代码:
<form action="subscribe.html">
<fieldset>
<input type="text" name="email" />
<input type="submit" value="Subscribe!" />
</fieldset>
</form>
与Thymeleaf一样,此模板更像是静态原型,而不是Web应用程序的模板。首先,表单中的 action 属性静态链接到模板文件本身,因此没有地方进行有用的URL重写。其次,提交按钮中的 value 属性的值以英语文本显示,但我们希望将其国际化。
输入 th:attr 属性,引入其更改设置标签属性值的能力:
<form action="subscribe.html" th:attr="action=@{/subscribe}">
<fieldset>
<input type="text" name="email" />
<input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/>
</fieldset>
</form>
这个概念非常简单:th:attr 只是简单的为一个属性分配值的表达式。创建了相应的控制器和消息文件后,处理该文件的结果将是:
<form action="/gtvg/subscribe">
<fieldset>
<input type="text" name="email" />
<input type="submit" value="¡Suscríbe!"/>
</fieldset>
</form>
除了新的属性值,还可以看到应用程序上下文名称已自动添加为URL前缀,如/gtvg/subscribe。
如果我们想一次设置多个属性怎么办?由于XML规则不允许在标记中设置属性两次,因此 th:attr 将采用逗号分隔的分配列表,例如:
<img src="../../images/gtvglogo.png"
th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
给定所需的消息文件,将输出:
<img src="/gtgv/images/gtvglogo.png" title="Logo de Good Thymes" alt="Logo de Good Thymes" />
为特定属性设置值
如前面所述,为属性设置值的做法如下所示:
<input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/>
但是,这么做比较繁琐,还难看。不如在其对应属性内设置值直接且方便。况且,这也不是创建模块最优雅的方法。这就是为啥Thymeleaf模板中 th:attr 很少使用的原因。通常都会使用其对应的 th:* 属性,而这些属性的任务就是为特定属性设置值(但不仅仅是像 th:attr 这样的任何属性)。
例如,要设置 value 属性,则使用 th:value:
<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
再如:
<form action="subscribe.html" th:action="@{/subscribe}">
还有很多这样的属性,每个属性都针对特定的HTML5属性。
th:abbr | th:accept | th:accept-charset |
th:accesskey | th:action | th:align |
th:alt | th:archive | th:audio |
th:autocomplete | th:axis | th:background |
th:bgcolor | th:border | th:cellpadding |
th:cellspacing | th:challenge | th:charset |
th:cite | th:class | th:classid |
th:codebase | th:codetype | th:cols |
th:colspan | th:compact | th:content |
th:contenteditable | th:contextmenu | th:data |
th:datetime | th:dir | th:draggable |
th:dropzone | th:enctype | th:for |
th:form | th:formaction | th:formenctype |
th:formmethod | th:formtarget | th:fragment |
th:frame | th:frameborder | th:headers |
th:height | th:high | th:href |
th:hreflang | th:hspace | th:http-equiv |
th:icon | th:id | th:inline |
th:keytype | th:kind | th:label |
th:lang | th:list | th:longdesc |
th:low | th:manifest | th:marginheight |
th:marginwidth | th:max | th:maxlength |
th:media | th:method | th:min |
th:name | th:onabort | th:onafterprint |
th:onbeforeprint | th:onbeforeunload | th:onblur |
th:oncanplay | th:oncanplaythrough | th:onchange |
th:onclick | th:oncontextmenu | th:ondblclick |
th:ondrag | th:ondragend | th:ondragenter |
th:ondragleave | th:ondragover | th:ondragstart |
th:ondrop | th:ondurationchange | th:onemptied |
th:onended | th:onerror | th:onfocus |
th:onformchange | th:onforminput | th:onhashchange |
th:oninput | th:oninvalid | th:onkeydown |
th:onkeypress | th:onkeyup | th:onload |
th:onloadeddata | th:onloadedmetadata | th:onloadstart |
th:onmessage | th:onmousedown | th:onmousemove |
th:onmouseout | th:onmouseover | th:onmouseup |
th:onmousewheel | th:onoffline | th:ononline |
th:onpause | th:onplay | th:onplaying |
th:onpopstate | th:onprogress | th:onratechange |
th:onreadystatechange | th:onredo | th:onreset |
th:onresize | th:onscroll | th:onseeked |
th:onseeking | th:onselect | th:onshow |
th:onstalled | th:onstorage | th:onsubmit |
th:onsuspend | th:ontimeupdate | th:onundo |
th:onunload | th:onvolumechange | th:onwaiting |
th:optimum | th:pattern | th:placeholder |
th:poster | th:preload | th:radiogroup |
th:rel | th:rev | th:rows |
th:rowspan | th:rules | th:sandbox |
th:scheme | th:scope | th:scrolling |
th:size | th:sizes | th:span |
th:spellcheck | th:src | th:srclang |
th:standby | th:start | th:step |
th:style | th:summary | th:tabindex |
th:target | th:title | th:type |
th:usemap | th:value | th:valuetype |
th:vspace | th:width | th:wrap |
th:xmlbase | th:xmllang | th:xmlspace |
一次设置多个值
有两个比较特殊的属性 th:alt-title 和 th:lang-xmllang 可用于同时设置两个属性相同的值。特别:
-
th:alt-title 将设置 alt 和 title。
-
th:lang-xmllang 将设置 lang 和 xml:lang。
例如:
<img src="../../images/gtvglogo.png"
th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />
或与其等价的:
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}" th:title="#{logo}" th:alt="#{logo}" />
有了 th:alt-title 属性,则可以很方便的同时设置值:
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}" th:alt-title="#{logo}" />
追加和前置
Thymeleaf还提供 th:attrappend 和 th:attrprepend 属性,将对它们求值的结果附加(后缀)或前缀(前缀)到现有属性值。
例如,您可能希望将要添加(未设置,只是添加)的CSS类的名称存储在上下文变量中,因为要使用的特定CSS类将取决于用户所做的操作之前:
<input type="button" value="Do it!" class="btn" th:attrappend="class=${' ' + cssStyle}" />
如果将 cssStyle 变量设置为来处理此模板 "warning",则会得到:
<input type="button" value="Do it!" class="btn warning" />
标准方言中还有两个特定的附加属性:th:classappend 和 th:styleappend 属性,用于在元素上添加CSS类或样式片段而不覆盖现有属性的值:
<tr th:each="prod : ${prods}" class="row" th:classappend="${prodStat.odd}? 'odd'">
固定布尔属性值
HTML具有布尔属性的概念,即没有值的属性,并且值为 1 即表示为“ true”。在XHTML中,这些属性仅有一个值,就是它本身。
例如checked:
<input type="checkbox" name="option2" checked /> <!-- HTML -->
<input type="checkbox" name="option1" checked="checked" /> <!-- XHTML -->
标准方言存在一些属性,这些属性可以通过评估条件来设置这些属性,因此,如果评估为 true,则该属性将设置为其固定值;如果评估为 false,则将不设置该属性:
<input type="checkbox" name="active" th:checked="${user.active}" />
标准方言中存在以下固定值布尔属性:
th:async | th:autofocus | th:autoplay |
th:checked | th:controls | th:declare |
th:default | th:defer | th:disabled |
th:formnovalidate | th:hidden | th:ismap |
th:loop | th:multiple | th:novalidate |
th:nowrap | th:open | th:pubdate |
th:readonly | th:required | th:reversed |
th:scoped | th:seamless | th:selected |
设置任何属性的值(默认属性处理器)
Thymeleaf提供了一个默认的属性处理器,即使我们在标准方言中没有为其定义任何特定的 th:* 处理器,它也允许我们设置任何属性的值 。
例如:
<span th:whatever="${user.name}">...</span>
将解析为:
<span whatever="John Apricot">...</span>
有好的支持HTML5属性和元素名
也可以使用完全不同的语法,以更友好的以HTML5方式将处理器应用于模板。
<table>
<tr data-th-each="user : ${users}">
<td data-th-text="${user.login}">...</td>
<td data-th-text="${user.name}">...</td>
</tr>
</table>
data-{prefix}-{name} 是HTML5中标准的自定义属性语法,而无需开发人员使用任何像 th:* 一样的命名空间名称。Thymeleaf使此语法自动适用于所有方言(不仅限于标准方言)。
还有一种用于指定自定义标记的语法:{prefix}-{name},它遵循W3C自定义元素规范(更大的W3C Web组件规范的一部分)。例如,这可以用于 th:block 元素(或 th-block),这将在后面的文章中进行说明。
重要提示:此语法是命名空间语法的补充 th:*,它不会替代它。完全没有打算将来弃用命名空间的语法。
笔者开通了个人微信公众号【银河架构师】,分享工作、生活过程中的心得体会,填坑指南,技术感悟等内容,会比博客提前更新,欢迎订阅。