- PVSM.RU - https://www.pvsm.ru -
Оглавление [1]
На текущий момент мы обсудили и создали домашнюю страницу, страницу профиля пользователя, а также страницу, позволяющую пользователям подписаться на нашу рассылку… но как насчет наших продуктов? Для этого нам понадобится способ перебора элементов в коллекции.
Для отображения продуктов на нашей странице /WEB-INF/templates/product/list.html мы используем таблицу. Каждый из продуктов отображается в строке (элемент <td>), поэтому создаем такую строку и инструктируем Thymeleaf повторить ее по одному разу для каждого продукта.
Стандартный диалект предлагает специальный атрибут: th:each.
Использование th:each
Для страницы списка продуктов понадобится метод контроллера, который извлекает список продуктов из уровня сервиса и добавляет его в контекст шаблона:
public void process(
final HttpServletRequest request, final HttpServletResponse response,
final ServletContext servletContext, final ITemplateEngine templateEngine)
throws Exception {
ProductService productService = new ProductService();
List<Product> allProducts = productService.findAll();
WebContext ctx = new WebContext(request, response, servletContext, request.getLocale());
ctx.setVariable("prods", allProducts);
templateEngine.process("product/list", ctx, response.getWriter());
}
И тогда мы будем использовать th:each в нашем шаблоне для итерации по списку продуктов:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all"
href="../../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
</head>
<body>
<h1>Product list</h1>
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
</tr>
<tr th:each="prod : ${prods}">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
</table>
<p>
<a href="../home.html" th:href="@{/}">Return to home</a>
</p>
</body>
</html>
Атрибут prod: ${prods}, которое вы видите выше, означает «для каждого элемента результат выполнения ${prods}, повторите этот фрагмент шаблона, используя текущий элемент переменной под названием prod». Давайте дадим имя каждой из вещей, которые мы видим:
Итерируемые значения
Класс java.util.List не является единственным, который может использоваться для итерации в Thymeleaf. Существует довольно большой набор объектов, которые подходят для th:each атрибута:
При использовании th:each, Thymeleaf предлагает механизм, полезный для отслеживания состояния вашей итерации: переменная состояния.
Переменные состояния определяются в пределах атрибута th:each и содержат следующие данные:
Посмотрим, как мы можем использовать итерационные свойства:
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
</tr>
<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
</table>
Переменная состояния (iterStat в этом примере) определяется в атрибуте th:each, записывая свое имя после самой переменной iter, разделенной запятой. Так же, как итеративная переменная, переменная статуса привязана к фрагменту кода, определяемому тегом, содержащим th:each атрибут.
Давайте посмотрим на результат обработки нашего шаблона:
<!DOCTYPE html>
<html>
<head>
<title>Good Thymes Virtual Grocery</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<link rel="stylesheet" type="text/css" media="all" href="/gtvg/css/gtvg.css" />
</head>
<body>
<h1>Product list</h1>
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
</tr>
<tr class="odd">
<td>Fresh Sweet Basil</td>
<td>4.99</td>
<td>yes</td>
</tr>
<tr>
<td>Italian Tomato</td>
<td>1.25</td>
<td>no</td>
</tr>
<tr class="odd">
<td>Yellow Bell Pepper</td>
<td>2.50</td>
<td>yes</td>
</tr>
<tr>
<td>Old Cheddar</td>
<td>18.75</td>
<td>yes</td>
</tr>
</table>
<p>
<a href="/gtvg/" shape="rect">Return to home</a>
</p>
</body>
</html>
Обратите внимание, что наша переменная status итерации отлично работает, устанавливая нечетный класс CSS только для нечетных строк.
Если вы явно не задаете переменную статуса, Thymeleaf всегда будет создавать ее для вас путем суффикса Stat к имени переменной итерации:
<table>
<tr>
<th>NAME</th>
<th>PRICE</th>
<th>IN STOCK</th>
</tr>
<tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'">
<td th:text="${prod.name}">Onions</td>
<td th:text="${prod.price}">2.41</td>
<td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
</table>
Иногда нам может понадобиться оптимизировать обход коллекций данных (например, из базы данных), чтобы эти коллекции извлекались только в том случае, если они действительно будут использоваться.
Фактически, это то, что может быть применено к любой части данных, но с учетом размера, который может иметь коллекция в памяти, извлечение коллекций, предназначенных для повторения, является наиболее распространенным случаем для этого сценария.
Чтобы поддержать этот механизм, Thymeleaf предлагает инструментарий для ленивой загрузки переменных контекста. Контекстные переменные, реализующие интерфейс ILazyContextVariable, скорее всего, расширяя его реализацию по умолчанию LazyContextVariable, будут разрешены в момент выполнения. Например:
context.setVariable(
"users",
new LazyContextVariable<List<User>>() {
@Override
protected List<User> loadValue() {
return databaseRepository.findAllUsers();
}
});
Эта переменная может использоваться без знания, ленивая ли она, например:
<ul>
<li th:each="u : ${users}" th:text="${u.name}">user name</li>
</ul>
Но в то же время никогда не будет инициализироваться (метод loadValue() никогда не будет вызываться), если условие оценивается как false в коде, например:
<ul th:if="${condition}">
<li th:each="u : ${users}" th:text="${u.name}">user name</li>
</ul>
Автор: pilot911
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/275401
Ссылки в тексте:
[1] Оглавление: https://habrahabr.ru/post/350862/
[2] Источник: https://habrahabr.ru/post/351132/?utm_campaign=351132
Нажмите здесь для печати.