• 검색 결과가 없습니다.

Iterable values

문서에서 Thymeleaf Tutorial: Using Thymeleaf (페이지 37-41)

The java.util.List class isn’t the onlyvalue that can be used for iteration in Thymeleaf. There is a quite complete set of objects that are considered iterable by a th:each attribute:

Any object implementing java.util.Iterable Any object implementing java.util.Enumeration.

Any object implementing java.util.Iterator, whose values will be used as they are returned by the iterator, without the need to cache all values in memory.

Any object implementing java.util.Map. When iterating maps, iter variables will be of class java.util.Map.Entry. Any array.

Any other object will be treated as if it were a single-valued list containing the object itself.

6.2 Keeping iteration status

When using th:each, Thymeleaf offers a mechanism useful for keeping track of the status of your iteration: the status variable.

Status variables are defined within a th:each attribute and contain the following data:

The current iteration index, starting with 0. This is the index property.

The current iteration index, starting with 1. This is the count property.

The total amount of elements in the iterated variable. This is the size property.

The iter variable for each iteration. This is the current property.

Whether the current iteration is even or odd. These are the even/odd boolean properties.

Whether the current iteration is the first one. This is the first boolean property.

Whether the current iteration is the last one. This is the last boolean property.

Let’s see how we could use it with the previous example:

<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>

The status variable (iterStat in this example) is defined in the th:each attribute by writing its name after the iter variable itself, separated by a comma. Just like the iter variable, the status variable is also scoped to the fragment of code defined by the tag holding the th:each attribute.

Let’s have a look at the result of processing our template:

<!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>

Note that our iteration status variable has worked perfectly, establishing the odd CSS class only to odd rows.

If you don’t explicitly set a status variable, Thymeleaf will always create one for you by suffixing Stat to the name of the iteration variable:

<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>

6.3 Optimizing through lazy retrieval of data

Sometimes we might want to optimize the retrieval of collections of data ( e.g. from a database) so that these collections are only retrieved if they are really going to be used.

Actually, this is something that can be applied to any piece of data, but given the size that in-memory collections might have, retrieving collections that are meant to be iterated is the most common case for this scenario.

In order to support this, Thymeleaf offers a mechanism to lazily load context variables. Context variables that implement the ILazyContextVariable interface – most probably by extending its LazyContextVariable default implementation – will be resolved in the moment of being executed. For example:

context.setVariable(

"users",

new LazyContextVariable<List<User>>() { @Override

protected List<User> loadValue() {

return databaseRepository.findAllUsers();

} });

This variable can be used without knowledge of its lazyness, in code such as:

<ul>

<li th:each="u : ${users}" th:text="${u.name}">user name</li>

</ul>

But at the same time, will never be initialized (its loadValue() method will never be called) if condition evaluates to false in code such as:

<ul th:if="${condition}">

<li th:each="u : ${users}" th:text="${u.name}">user name</li>

</ul>

문서에서 Thymeleaf Tutorial: Using Thymeleaf (페이지 37-41)

관련 문서