openplanning

Vòng lặp trong Thymeleaf

  1. Vòng lặp (Loop)
  2. Các ví dụ với vòng lặp th:each

1. Vòng lặp (Loop)

Thymeleaf cung cấp cho bạn vòng lặp 'each', và bạn có thể sử dụng nó thông qua thuộc tính (attribue) th:each. Đây là vòng lặp duy nhất được hỗ trợ trong Thymeleaf.
Vòng lặp này chấp nhận một vài loại dữ liệu như:
  • Các đối tượng thực hiện (implements) interface java.util.Iterable.
  • Các đối tượng thực hiện (implements) interface java.util.Map.
  • Các mảng (Arrays)
Cú pháp đơn giản nhất của th:each:
<someHtmlTag th:each="item : ${items}"> 
     ....
</someHtmlTag>
Thẻ <th:block> là một thẻ ảo trong Thymeleaf, nó không tương ứng với bất kỳ thẻ nào của HTML, nhưng nó rất có ích trong nhiều trường hợp, chẳng hạn bạn có thể đặt thuộc tính (attribute) th:each trong thẻ này.
<th:block th:each="item : ${items}">
     ....
</th:block>
Ví dụ đơn giản với vòng lặp th:each:
(Java Spring)
@RequestMapping("/loop-simple-example")
public String loopExample1(Model model) {
    String[] flowers = new String[] { "Rose", "Lily", "Tulip", "Carnation", "Hyacinth" };
    model.addAttribute("flowers", flowers);
    return "loop-simple-example";
}
loop-simple-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
</head>
<body>
    <h1>th:each</h1>
    <ul>
        <th:block th:each="flower : ${flowers}">
            <li th:utext="${flower}">..</li>
        </th:block>
    </ul>
</body>
</html>
Đầu ra (Output):
(Output)
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
</head>
<body>
    <h1>th:each</h1>
    <ul>
            <li>Rose</li>
            <li>Lily</li>
            <li>Tulip</li>
            <li>Carnation</li>
            <li>Hyacinth</li>
    </ul>
</body>
</html>
Cú pháp đầy đủ của th:each bao gồm 2 biến, biến phần tử (item variable) và biến trạng thái (state variable).
<someHtmlTag th:each="item, iState : ${items}">
       .....
</someHtmlTag>

<!-- OR: -->

<th:block th:each="item, iState : ${items}">
       .....
</th:block>
Biến trạng thái (State variable) là một đối tượng hữu ích, nó chứa các thông tin cho bạn biết trạng thái hiện tại của vòng lặp, chẳng hạn như số phần tử của vòng lặp, chỉ số hiện tại của vòng lặp,...
Dưới đây là danh sách các thuộc tính (property) của biến trạng thái (state variable):
Property
Mô tả
index
Chỉ số hiện tại của phép lặp (iteration), bắt đầu với số 0.
count
Số phần tử đã được xử lý cho tới hiện tại.
size
Tổng số phần tử trong danh sách.
even/odd
Kiểm tra xem chỉ số (index) hiện tại của phép lặp (iteration) là chẵn hay lẻ.
first
Kiểm tra xem lần lặp hiện tại là lần lặp đầu tiên hay không?
last
Kiểm tra xem lần lặp hiện tại là lần lặp cuối hay không?
Ví dụ với th:each và biến trạng thái (state variable):
(Java Spring)
@RequestMapping("/loop-example")
public String loopExample(Model model) {
    String[] flowers = new String[] { "Rose", "Lily", "Tulip", "Carnation", "Hyacinth" }; 
    model.addAttribute("flowers", flowers);
    return "loop-example";
}
loop-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
    <style>table th, table td {padding: 5px;}</style>
</head>
<body>
    <h1>th:each</h1>
    <table border="1">
        <tr>
          <th>index</th>
          <th>count</th>
          <th>size</th>
          <th>even</th>
          <th>odd</th>
          <th>first</th>
          <th>last</th>
          <th>Flower Name</th>
        </tr>
        <tr th:each="flower, state : ${flowers}">
          <td th:utext="${state.index}">index</td>
          <td th:utext="${state.count}">count</td>
          <td th:utext="${state.size}">size</td>
          <td th:utext="${state.even}">even</td>
          <td th:utext="${state.odd}">odd</td>
          <td th:utext="${state.first}">first</td>
          <td th:utext="${state.last}">last</td>
          <td th:utext="${flower}">Flower Name</td>
        </tr>
    </table>
</body>
</html>
Kết quả:

2. Các ví dụ với vòng lặp th:each

Một vài ví dụ khác giúp bạn hiểu hơn về vòng lặp trong Thymeleaf:
  • Ví dụ sử dụng vòng lặp với đối tượng List.
  • Ví dụ sử dụng vòng lặp với đối tượng Map.
  • Tạo một mảng trực tiếp trên Thymeleaf Template và sử dụng vòng lặp với đối tượng này.
Person.java
package org.o7planning.thymeleaf.model;

public class Person {
    private Long id;
    private String fullName;
    private String email;
    public Person() {
    }
    public Person(Long id, String fullName, String email) {
        this.id = id;
        this.fullName = fullName;
        this.email = email;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getFullName() {
        return fullName;
    }
    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}
th:each & List
Ví dụ với th:eachList:
(Java Spring)
@RequestMapping("/loop-list-example")
public String loopListExample(Model model) {
    Person tom = new Person(1L, "Tom", "tom@waltdisney.com");
    Person jerry = new Person(2L, "Jerry", "jerry@waltdisney.com");
    Person donald = new Person(3L, "Donald", "donald@waltdisney.com");
    List<Person> list = new ArrayList<Person>();
    list.add(tom);
    list.add(jerry);
    list.add(donald);
    model.addAttribute("people", list);
    return "loop-list-example";
}
loop-list-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
    <style>
      table th, table td {padding: 5px;}
      .row  {
         font-style: italic;
      }
      .even-row {
         color: black;
      }
      .odd-row {
         color: blue;
      }
    </style>
</head>
<body>
    <h1>th:each</h1>
    <table border="1">
        <tr>
          <th>No</th>
          <th>Full Name</th>
          <th>Email</th>
        </tr>
        <tr th:each="person, state : ${people}"
               class="row" th:classappend="${state.odd} ? 'odd-row' : 'even-row'">
          <td th:utext="${state.count}">No</td>
          <td th:utext="${person.fullName}">Full Name</td>
          <td th:utext="${person.email}">Email</td>  
        </tr>
    </table>
</body>
</html>
Kêt quả:
th:each & Map
Ví dụ với th:eachMap:
(Java Spring)
@RequestMapping("/loop-map-example")
public String loopMapExample(Model model) {
    Person tom = new Person(1L, "Tom", "tom@waltdisney.com");
    Person jerry = new Person(2L, "Jerry", "jerry@waltdisney.com");
    Person donald = new Person(3L, "Donald", "donald@waltdisney.com");
    // String: Phone Number.
    Map<String, Person> contacts = new HashMap<String, Person>();
    contacts.put("110033", tom);
    contacts.put("110055", jerry);
    contacts.put("110077", donald);
    model.addAttribute("contacts", contacts);
    return "loop-map-example";
}
loop-map-example.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
    <style>
      table th, table td {padding: 5px;}
      .row  {
         font-style: italic;
      }
      .even-row {
         color: black;
      }
      .odd-row {
         color: blue;
      }
    </style>
</head>
<body>
    <h1>th:each</h1>
    <table border="1">
        <tr>
          <th>No</th>
          <th>Phone</th>
          <th>Full Name</th>
          <th>Email</th>
        </tr>
        <tr th:each="mapItem, state : ${contacts}"
               class="row" th:classappend="${state.odd} ? 'odd-row' : 'even-row'">
          <td th:utext="${state.count}">No</td>
          <td th:utext="${mapItem.key}">Phone Number</td>
          <td th:utext="${mapItem.value.fullName}">Email</td>  
          <td th:utext="${mapItem.value.email}">Email</td>
        </tr>
    </table>
</body>
</html>
Kết quả:
Other example:
Ví dụ: Tạo một mảng trực tiếp trong Thymeleaf Template và sử dụng vòng lặp.
loop-other-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Loop</title>
<style>
table th, table td {
    padding: 5px;
}
</style>
</head>
<body>
    <h1>th:each</h1>
    <!-- Create an Array: -->
    <th:block th:with="flowers = ${ {'Rose', 'Lily', 'Tulip'} }">
        <table border="1">
            <tr>
                <th>No</th>
                <th>Flower</th>
            </tr>
            <tr th:each="flower, state : ${flowers}">
                <td th:utext="${state.count}">No</td>
                <td th:utext="${flower}">Flower</td>
            </tr>
        </table>
    </th:block>
</body>
</html>
Kết quả: