betacode

Цикл в Thymeleaf

  1. Цикл (Loop)
  2. Примеры с циклом th:each

1. Цикл (Loop)

Thymeleaf предоставляет вам цикл 'each', и вы можете его использовать через атрибут (attribue) th:each. Это единственный цикл, поддерживаемый в Thymeleaf.
Данный цикл принимает некоторые виды данных как:
  • Объекты выполняют (implements) интерфейс java.util.Iterable.
  • Объекты выполняют (implements) интерфейс java.util.Map.
  • Массивы (Arrays)
Самый простой синтаксис у th:each:
<someHtmlTag th:each="item : ${items}"> 
     ....
</someHtmlTag>
Тег <th:block> это виртуальный тег в Thymeleaf, он не соответствует никакому тегу HTML, но во многих случаях он очень полезен, например вы можете настроить атрибут (attribute) th:each в данном теге.
<th:block th:each="item : ${items}">
     ....
</th:block>
Простой пример с циклом 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>
Выход (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>
Полный синтаксис th:each включает 2 переменные, переменная элемента (item variable) и переменная состояния (state variable).
<someHtmlTag th:each="item, iState : ${items}">
       .....
</someHtmlTag>

<!-- OR: -->

<th:block th:each="item, iState : ${items}">
       .....
</th:block>
Переменная состояния (State variable) это полезный объект, содержащий информацию текущего состояния цикла, например количество элементов цикла, текущий индекс цикла,...
Ниже является список свойств (property) переменной состояния (state variable):
Свойство
Описание
index
Текущий индекс повтора (iteration), начиная с 0.
count
Количество обработанный элементов до настоящего момента.
size
Сумма элементов в списке.
even/odd
Проверяет текущий индекс (index) повтора (iteration) является четным или нечетными.
first
Проверяет является ли настоящий повтор первым или нет?
last
Проверяет является ли настоящий повтор последним или нет?
Пример с th:each и переменной состояния (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>
Результат:

2. Примеры с циклом th:each

Другие примеры, чтобы вы лучше поняли про цикл в Thymeleaf:
  • Пример использования цикла с объектом List.
  • Пример использования цикла с объектом Map.
  • Создать массив напрямую на Thymeleaf Template и использовать цикл для данного объекта.
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
Пример с th:each и List:
(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>
Результат:
th:each & Map
Пример сi th:each и Map:
(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>
Результат:
Other example:
Пример: Создать массив напрямую в Thymeleaf Template и использовать цикл.
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>
Результат: