Thymeleaf變量
- Thymeleaf
1.簡介
在本教程中,我們將看一下Thymeleaf中的變量。我們將創建一個Spring Boot示例,該示例將獲取Ba文章列表並將其顯示在Thymeleaf HTML模板中。
2. Maven依賴
要使用Thymeleaf,我們需要添加spring-boot-starter-thymeleaf
和spring-boot-starter-web
依賴項:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3. Web控制器
首先,我們將創建一個具有GET端點的Web控制器,該端點將返回包含Ba文章列表的頁面。
@GetMapping
註釋的方法將採用一個參數– Model
。它包含可在Thymeleaf模板中進一步使用的所有全局變量。在我們的例子中,模型只有一個參數-文章列表。
Article
類將包含兩個String
字段, name
和url
:
public class Article {
private String name;
private String url;
// constructor, getters and setters
}
我們控制器方法的返回值應該是所需Thymeleaf模板的名稱。該名稱應對應於src/resource/template
目錄中的HTML文件。在我們的例子中,它將是src/resource/template/articles-list.html
。
讓我們快速看一下我們的Spring控制器:
@Controller
@RequestMapping("/api/articles")
public class ArticlesController {
@GetMapping
public String allArticles(Model model) {
model.addAttribute("articles", fetchArticles());
return "articles-list";
}
private List<Article> fetchArticles() {
return Arrays.asList(
new Article(
"Introduction to Using Thymeleaf in Spring",
"https://www.baeldung.com/thymeleaf-in-spring-mvc"
),
// a few other articles
);
}
}
運行該應用程序後,將在http://localhost:8080/articles
提供articles頁面。
4. Thymeleaf模板
現在,讓我們進入Thymeleaf HTML模板。它應該具有標準的HTML文檔結構,僅帶有附加的Thymeleaf命名空間定義:
<html xmlns:th="http://www.thymeleaf.org">
我們將在其他示例中將其用作模板,在這裡我們將僅替換<main>
標記的內容:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Variables</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<main>
...
</main>
</body>
</html>
5.定義變量
我們可以通過兩種方式在Thymeleaf模板中定義變量。第一種選擇是在遍歷數組時採用單個元素:
<div th:each="article : ${articles}">
<a th:text="${article.name}" th:href="${article.url}"></a>
</div>
結果,我們將得到一個<div>
其中包含幾個<a>
元素,它們與articles
變量中的文章數相對應。
另一種方法是基於另一個變量定義一個新變量。例如,我們可以採用Articles數組的第一個元素:
<div th:with="firstArticle=${articles[0]}">
<a th:text="${firstArticle.name}" th:href="${firstArticle.url}"></a>
</div>
或者我們可以創建一個僅包含文章名稱的新變量:
<div th:each="article : ${articles}", th:with="articleName=${article.name}">
<a th:text="${articleName}" th:href="${article.url}"></a>
</div>
在上面的示例中, ${article.name}
和${articleName}
片段是可替換的。
也可以定義多個變量。例如,我們可以創建兩個單獨的變量來保存商品名稱和URL:
<div th:each="article : ${articles}" th:with="articleName=${article.name}, articleUrl=${article.url}">
<a th:text="${articleName}" th:href="${articleUrl}"></a>
</div>
6.變量範圍
在控制器中傳遞給Model
變量具有全局作用域。這意味著它們可以在我們的HTML模板的每個位置使用。
另一方面,HTML模板中定義的變量具有局部作用域。它們只能在定義它們的元素範圍內使用。
例如,下面的代碼是正確的,因為<a>
元素位於firstDiv
:
<div id="firstDiv" th:with="firstArticle=${articles[0]}">
<a th:text="${firstArticle.name}" th:href="${firstArticle.url}"></a>
</div>
另一方面,當我們嘗試在另一個div
firstArticle
時:
<div id="firstDiv" th:with="firstArticle=${articles[0]}">
<a th:text="${firstArticle.name}" th:href="${firstArticle.url}"></a>
</div>
<div id="secondDiv">
<h2 th:text="${firstArticle.name}"></h2>
</div>
我們會在編譯時得到一個異常,說firstArticle
為null
:
org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'name' cannot be found on null
這是因為<h2>
firstDiv,
定義的變量,該變量超出範圍。
如果我們仍然需要使用firstArticle
內部變量secondDiv
,我們需要再次定義它secondDiv
或包裝這兩個div
在一個共同的元素標記,並定義firstArticle
在裡面。
7.更改變量的值
在給定範圍內也可以覆蓋變量的值:
<div id="mainDiv" th:with="articles = ${ { articles[0], articles[1] } }">
<div th:each="article : ${articles}">
<a th:text="${article.name}" th:href="${article.url}"></a>
</div>
</div>
在上面的示例中,我們重新定義了articles
變量,使其僅具有兩個前元素。
請注意,在mainDiv,
articles
變量仍將在控制器中傳遞其原始值。
8.結論
在本教程中,我們學習瞭如何在Thymeleaf中定義和使用變量。