Search buenodc

Passando uma coleção para visão

Até então passamos um único objeto para a visão, mas e se quisermos passar uma coleção de objetos? Por exemplo uma lista de produtos em vez de apenas um produto.

Para isso vamos precisar fazer algumas alterações em nosso controlador:

  • Vamos adicionar uma lista no nível da classe para que essa informação possa ser compartilhada entre os métodos.
  • Vamos inicializar a lista com 3 valores iniciais no construtor da classe.
  • Vamos alterar os dados guardados no contêiner de dados (model) para a coleção que criamos
@Controller
public class ProductController {

    List<Product> products = new ArrayList<Product>();

    ProductController() {
        products.add(new Product("Notebook", "Notebook Dell", 3500.00));
        products.add(new Product("Smartphone", "Samsung S3", 1500.00));
        products.add(new Product("Monitor", "Monitor LG 24", 500.00));
    }
    
    @GetMapping("/products")
    public String index(Model model) {
        model.addAttribute("products", products);
        return "list";
    }
    
}

Se preferir você pode utilizar a classe Arrays para inicializar a lista com os valores iniciais:

@Controller
public class ProductController {

    List<Product> products = Arrays.asList(
        new Product("Notebook", "Notebook Dell", 3500.00),
        new Product("Smartphone", "Samsung S3", 1500.00),
        new Product("Monitor", "Monitor LG 24", 500.00)
    );

    ...

Agora precisamos alterar a visão, visto que deixamos de receber um único objeto e passamos a receber uma coleção de objetos. Para esse cenário o Thymeleaf provê um novo atributo chamado th:each que nos permite iterar sobre uma coleção de objetos com a seguinte sintaxe:

th:each="element : ${collection}

Onde element é o nome que você deseja dar para cada elemento da coleção e collection é a coleção que você deseja iterar.

Vamos alterar a visão list para que de fato agora ela exiba uma lista de produtos e não mais apenas um elemento.

<table>
    <tr>
        <th>Name</th>
        <th>Description</th>
        <th>Price</th>
    </tr>
    <tr th:each="product : ${products}">
        <td th:text="${product.name}"></td>
        <td th:text="${product.description}"></td>
        <td th:text="${product.price}"></td>
    </tr>
</table>

Com esse atributo podemos percorrer a coleção de produtos e exibir cada um deles em uma linha da tabela.

Rode o código no navegador, veja o código fonte gerado e perceba que apesar de termos escrito apenas uma linha da tabela (tr) em nosso código, o Thymeleaf gerou 3 linhas da tabela, uma para cada produto da coleção.