本文只適用於不會Java對HTML語言有基礎的程序員們,是瀏覽了各大博客后收集整理,重新編輯的一篇文章,希望能對大家有所幫助。最后本文如果有哪里寫錯的,希望各位大神們能夠批評指正,謝謝大家!
對於Thymeleaf,網上特別官方的解釋無非就是:網站或者獨立應用程序的新式的服務端java模板引擎,可以執行HTML,XML,JavaScript,CSS甚至純文本模板。這個解釋沒有任何問題,它確實是建立在Java的基礎之上的,但是像我這種只會前端不懂Java的人,其實也可以運用它。了解angular的人在看到Thymeleaf就會感到驚喜,它們在形式上其實是比較相似的。那么,Thymeleaf需要從那里看起?作為Java小白,剛開始看了網上那么多Thymeleaf文章也看不出個所以然,今天好不容易才整理出頭緒,接下來就開始切入正題:
<td th:text="${food.name}">noodles</td>
如上圖,后台傳出的food.name會將靜態數據“noodles”替換掉,若訪問靜態頁面,則顯示數據“noodles”。是不是和angular很像?下面我們就來換一種方式,不同於其他博客上的方式來介紹Thymeleaf。
當然,首先大家要先知道th簡單表達式:
一、th簡單表達式:
① ${...} 變量表達式:
<input type="text" name="userName" value="Beyrl" th:value="${user.name}" />
上述代碼為引用user對象的name屬性值。
② *{...} 選擇表達式:
<div th:object="${session.user}"> <p>Nationality: <span th:text="*{nationality}">XXXX</span>.</p> </div>
選擇表達式一般跟在th:object后,直接選擇object中的屬性。
③ #{...} 消息文字表達式:
<p th:utext="#{home.welcome}">Welcome to our grocery store!</p>
④ @{...} 鏈接url表達式:
<a href="details.html" th:href="@{/webPage/details(orderId=${o.id})}">view</a>
@{……}支持決定路徑和相對路徑。其中相對路徑又支持跨上下文調用url和協議的引用(//code.jquery.com/jquery-2.0.3.min.js)。
<img src="../../webPage/food/images/pizza.jpg" th:src="@{${path}}" alt="披薩" />
當理解了這四個表達式后,我就信心滿滿的去向下看文檔,然后我發現我看不懂了。。。因為我不理解什么是th:field='';th:action='';諸如此類的好多好多,后來在一個博客上看到這一類的是所謂的Thymeleaf的屬性,或者是常用的th:標簽,下面我們就來整理學習一下這些標簽:
這是在一個博客上看到的整理的較全的圖片,還有一個更全的,那個太多了,會嚇到初學者,不知道你們會不會,反正我是被嚇到了。。。
下面我們會詳細介紹一些常用的標簽:
二、th常用標簽:
1.th:id:
類似html標簽中的id屬性。
<div class="student" th:id = "food+(${pizza.index}+1)"></div>
2.th:text:與th:utext:
即文本顯示,可對表達式或變量求值,並將結果顯示在其被包含的HTML標簽內,替換原有HTML文本。這里需要與th:utext:區分開,th:text:例子如下:
若 restraunt.welcome=welcome to our <b>delicious</b>restaurant! 那么,用 <p h:text="#{restaurantt.welcome}"></p> 解析的結果為: welcome to our <b>delicious</b>restaurant! ,
也就是說,會輸出 welcome to our <b>delicious</b>restaurant</> 當然,我們是不會希望頁面上出現<和e>的,這時候,我們就需要使用th:utext:來進行轉義,即用 <p h:utext="#{restaurant.welcome}"></p>
所以最終輸出的結果為:welcome to our delicious restaurant!
3.th:object:
用於表單數據對象綁定,將表單綁定到后台controller的一個JavaBean參數,常與th:field一起使用進行表單數據綁定。選擇表達式一般跟在th:object后,直接取object中的屬性。
這里有一個需要注意的點:*{...}表達式的值是在選定的對象而不是整個context的map。也就是說,如果沒有選定的對象,*{...}和${...}沒有區別,請看下面的例子:
<div th:object="${session.user}"> <p>姓名:<span th:text="*{Name}">noodles</span></p> <p>年齡:<span th:text="*{age}">24</span></p> <p>國籍:<span th:text="*{nationlity}">中國</span></p> </div>
上面這段代碼相當於:
<div> <p>姓名:<span th:text="${session.user.Name}">noodles</span></p>
<p>年齡:<span th:text="${session.user.age}">24</span></p>
<p>國籍:<span th:text="${session.user.nationlity}">中國</span></p></div>
4.th:field:上面提到了一個新標簽,th:field:,常用於表單字段綁定。通常與th:object一起使用。 屬性綁定、集合綁定。
<form th:action="@{/bb}" th:object="${user}" method="post" th:method="post"> <input type="text" th:field="*{name}"/> <input type="text" th:field="*{msg}"/> <input type="submit"/> </form>
5.th:action:定義后台控制器路徑,類似<form>標簽的action屬性。
<form action="subscribe.html" th:action="@{/subscribe}">
6.th:href:定義超鏈接,類似<a>標簽的href 屬性。value形式為@{/logout}.
<!-- 輸出: 'http://localhost:8080/gtvg/order/details?orderId=3' --> <a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a> <!-- 輸出: '/gtvg/order/details?orderId=3' --> <a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a> <!-- 輸出: '/gtvg/order/3/details' --> <a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
7.th:src:用於外部資源引入,類似於<script>標簽的src屬性,常與@{}一起使用。
<script th:src="@{/js/jquery/jquery-2.4.min.js}">
8.th:value:用於標簽賦值,類似<option>標簽的value屬性。
<option th:value="soup">soup</option> <input id="msg" th:value="${msg}" />
9.th:if or th:unless:條件判斷,支持布爾值,數字(非零為true),字符,字符串等.
<div th:if="${restaurant.index} == 0">... I love eating(do something at here) ...</div> <span th:if="${food.price lt 100}" class="offer">Special desert!</span> /*不能用"<",">"等符號,要用"lt"等替代*/ <select class='form-control' name="skill[4].proficiency"> <option >掌握程度</option> <option th:if="${skill.level eq '一般'}" th:selected="selected">一般</option> <option th:if="${skill.level eq '熟練'}" th:selected="selected">熟練</option> <option th:if="${skill.level eq '精通'}" th:selected="selected">精通</option> </select>
這里有兩個需要注意的點:先看下面兩行代碼,
<div th:if="${user.isAdmin()} == false"> ...
<div th:if="${user.isAdmin() == false}"> ...
在這個例子中,==false是寫在了\({...}的外邊,所以使Thymeleaf本身在支持它,如果寫在了\){...}的里邊,則變為由OGNL或SpringEL庫來支持它。(***這里目前我還未明白是什么意思,希望明白的大神能告訴我這個問題***)
而null值也可以這么使用:
<div th:if="${variable.something} == null"> ...
th:if不光可以使用布爾值,以下規則都可以:
- 如果值不為空:如果值為null,th:if將為false
- 如果值為布爾型並且為true
- 如果值為數值型並且不為0
- 如果值為character並且不為0
- 如果值為String,並且不為"false","off"和"no"
- 如果值不為布爾型,數值型,character或String的任意類型
● 如果值為null,th:if將為false
th:if還有一個互逆的表達式為th:unless,還繼續用之前的例子作一個演示:
<a href="comments.html" th:href="@{/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">查看</a>
下面的是一個th:if 例子,大家可以照着套一下。
<table> <tr> <th>食物名稱</th> <th>食物價格</th> <th>可現做</th> <th>食客評價</th> </tr> <tr th:each="prod:${prods}"> <td th:text="${prod.name}">醋溜土豆絲</td> <td th:text="${#numbers.formatDecimal(prod.price,0,2)}">2.41</td> <td th:text="${prod.isReady}?#{true}:#{false}">yes</td> <td> <span th:text=${#lists.size(prod.comments)}>2</span>個評價 <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:if="${not #lists.isEmpty(prod.comments)}">查看</a> </td> </tr> </table>
如果產品有評論,那么我們就創建一個跳轉到評論頁面的超鏈接,並且使用產品ID作為參數。
10.th:switch 和th:case:選擇語句。 th:case="*"表示default case。注意:一旦一個th:case被判斷為真,那么其他的同等級的th:case都將被判斷為假
<div th:switch="${user.role}"> <p th:case="'admin'">超級管理員用戶</p> <p th:case="#{roles.manager}">管理員用戶</p> <p th:case="*">其他用戶</p> </div>
11.th:with:定義變量,th:with="isEven=${prodStat.count}%2 == 0",定義多個變量可以用逗號分隔。
<div th:with="firstPer=${persons[0]}"> <p> The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>. </p> </div>
當th:with被處理,firstPer變量創建一個局部變量和變量添加到map自上下文,以便它是用於評估和其他上下文中聲明的變量從開始,但只有包含< div >標記的范圍內。
div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">
<p> The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>. </p> <p> But the name of the second person is <span th:text="${secondPer.name}">Marcus Antonius</span>. </p> </div>
th:with屬性允許重用變量定義在相同的屬性:
<div th:with="company=${user.company + ' Co.'},account=${accounts[company]}">...</div>
12.th:remove:移除除了第一個外的靜態數據,用第一個tr標簽進行循環迭代顯示:
<tbody th:remove="all-but-first"> //將后台傳出的 productList 的集合進行迭代,用product參數接收,通過product訪問屬性值 <tr th:each="product:${productList}"> //用count進行統計,有順序的顯示 <td th:text="${productStat.count}">1</td> <td th:text="${product.description}">Red Chair</td> <td th:text="${'$' + #numbers.formatDecimal(product.price, 1, 2)}">$123</td> <td th:text="${#dates.format(product.availableFrom, 'yyyy-MM-dd')}">2014-12-01</td> </tr> <tr> <td>White table</td> <td>$200</td> <td>15-Jul-2013</td> </tr> <tr> <td>Reb table</td> <td>$200</td> <td>15-Jul-2013</td> </tr> <tr> <td>Blue table</td> <td>$200</td> <td>15-Jul-2013</td> </tr> </tbody>