Como fazer if-else no Thymeleaf?

132

Qual é a melhor maneira de fazer um simples if- elseno Thymeleaf?

Quero alcançar no Thymeleaf o mesmo efeito que

<c:choose>
  <c:when test="${potentially_complex_expression}">
     <h2>Hello!</h2>
  </c:when>
  <c:otherwise>
     <span class="xxx">Something else</span>
  </c:otherwise>
</c:choose>

em JSTL.

O que eu descobri até agora:

<div th:with="condition=${potentially_complex_expression}" th:remove="tag">
    <h2 th:if="${condition}">Hello!</h2>
    <span th:unless="${condition}" class="xxx">Something else</span>
</div>

Não quero avaliar potentially_complex_expressionduas vezes. Por isso, introduzi a variável local condition. Ainda não gosto de usar ambos th:if="${condition}e th:unless="${condition}".

Uma coisa importante é que eu uso duas tags HTML diferentes: digamos h2e span.

Você pode sugerir uma maneira melhor de conseguir isso?

Maciej Ziarko
fonte

Respostas:

208

Thymeleaf tem um equivalente a <c:choose>e <c:when>: a th:switche th:caseatributos introduzido em Thymeleaf 2.0.

Eles funcionam como você esperaria, usando *o caso padrão:

<div th:switch="${user.role}"> 
  <p th:case="'admin'">User is an administrator</p>
  <p th:case="#{roles.manager}">User is a manager</p>
  <p th:case="*">User is some other thing</p> 
</div>

Veja isso para obter uma explicação rápida da sintaxe (ou dos tutoriais do Thymeleaf).

Isenção de responsabilidade : Conforme exigido pelas regras do StackOverflow, sou o autor do Thymeleaf.

Daniel Fernández
fonte
ok but..how fazer invoco um javascript com base no tipo de cliente (ou seja anônima ou logado) ...
Sorte
1
Veja o capítulo sobre "inlining Texto", especificamente a seção "JavaScript inlining" no "Usando Thymeleaf" tutorial em thymeleaf.org/documentation.html
Daniel Fernández
E como posso fazer th: ativar um valor iterator.index? Eu quero fazer um conjunto de casos quando o valor for <5 e alternar para o caso padrão se o valor for> 5 #
Loser Coder
@ DanielFernández: você pode me ajudar com stackoverflow.com/questions/48499723/… . Não pude marcar você diretamente na pergunta. Muito preso.
jetty
98

Eu tentei esse código para descobrir se um cliente está logado ou anônimo. Eu fiz usando as expressões th:ife th:unlesscondicionais. Uma maneira bem simples de fazer isso.

<!-- IF CUSTOMER IS ANONYMOUS -->
<div th:if="${customer.anonymous}">
   <div>Welcome, Guest</div>
</div>
<!-- ELSE -->
<div th:unless="${customer.anonymous}">
   <div th:text=" 'Hi,' + ${customer.name}">Hi, User</div>
</div>
Por sorte
fonte
5
Isso não responde à pergunta do OP, porque se tratava de evitar a duplicação de expressões complexas. E, como outras soluções, isso quebra a idéia de "modelos naturais", que é um dos principais pontos de venda da Thymeleaf. Não tenho certeza do que fazer sobre isso sozinho, mas só queria salientar se alguém tiver uma resposta.
Stephen Harrison
@Lucky, isso me dá um erro EL1007E: (pos 0): A propriedade ou o campo 'Status' não pode ser encontrado
Jesse
@ Jackie No exemplo acima, customer é um objeto e anonymous é um campo booleano na classe Customer. Verifique se o seu objeto não é nulo e se o nome do campo está correto.
Lucky
25

Gostaria de compartilhar meu exemplo relacionado à segurança, além de Daniel Fernández.

<div th:switch="${#authentication}? ${#authorization.expression('isAuthenticated()')} : ${false}">
    <span th:case="${false}">User is not logged in</span>
    <span th:case="${true}">Logged in user</span>
    <span th:case="*">Should never happen, but who knows...</span>
</div>

Aqui está uma expressão complexa com objetos utilitários 'autenticação' e 'autorização' misturados, que produzem resultados 'verdadeiro / falso' para o código do modelo da folha timelapse.

Os objetos utilitários 'authentication' e ' permission ' vieram da biblioteca thymeleaf extras springsecurity3 . Quando o objeto 'authentication' não está disponível, OU authentication.expression ('isAuthenticated ()') é avaliado como 'false', a expressão retorna $ {false}, caso contrário, $ {true}.

sem graça
fonte
19

Você pode usar

If-then-else:  (if) ? (then) : (else)

Exemplo:

'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

Pode ser útil para as novas pessoas que fazem a mesma pergunta.

Jad B.
fonte
11

Outra solução - você pode usar a variável local:

<div th:with="expr_result = ${potentially_complex_expression}">
    <div th:if="${expr_result}">
        <h2>Hello!</h2>
    </div>
    <div th:unless="${expr_result}">
        <span class="xxx">Something else</span>
    </div>
</div>

Mais sobre variáveis ​​locais:
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#local-variables

jareks
fonte
Acho que você adicionou um sinal "=" extra ao seu código. Por favor, verifique novamente e corrija se eu estiver certo.
sorte
Na minha opinião, o código está ok. Não sei qual sinal '=' extra você quer dizer.
jareks
Sim, o código está ok. Desculpe, eu confundi com o lugar th:eachonde a expressão tem, em :vez de=
Lucky
Mas esta resposta está muito próxima da minha solução. Ao fazer o th: with expression parece redundante para mim. Basicamente, esta solução usa as instruções condicionais th: if e th: except.
Sorte
Eu acho que não é redundante. Se você usar apenas th: se e th: menos expressão complexa seria executado duas vezes ...
jareks
9

Em um caso mais simples (quando as tags html são iguais):

<h2 th:text="${potentially_complex_expression} ? 'Hello' : 'Something else'">/h2>
Grigory Kislin
fonte
Você sabe como adicionar traduções para 'Hello' e 'Something else' nesta expressão?
Laura
@Laura Você pode usar a internacionalização e carregar diferentes traduções de idiomas com base na localização do arquivo de propriedades. Veja looksok.wordpress.com/tag/internationalization , marcelustrojahn.com/2016/12/…
Lucky
7

Outra solução é usar apenas notpara obter a negação oposta:

<h2 th:if="${potentially_complex_expression}">Hello!</h2>
<span class="xxx" th:if="${not potentially_complex_expression}">Something else</span>

Conforme explicado na documentação , é a mesma coisa que usar th:unless. Como outras respostas explicaram:

Além disso, th:ifpossui um atributo inverso th:unless, que poderíamos ter usado no exemplo anterior, em vez de usar uma expressão que não esteja dentro da expressão OGNL

Usar nottambém funciona, mas IMHO é mais legível de usar em th:unlessvez de negar a condição not.

Pau
fonte
2
<div th:switch="${user.role}"> 
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
<p th:case="*">User is some other thing</p> 
</div>


<div th:with="condition=${potentially_complex_expression}" th:remove="tag">
<h2 th:if="${condition}">Hello!</h2>
<span th:unless="${condition}" class="xxx">Something else</span>
</div>
Daria Yu
fonte
1
<div style="width:100%">
<span th:each="i : ${#numbers.sequence(1, 3)}">
<span th:if="${i == curpage}">
<a href="/listEmployee/${i}" class="btn btn-success custom-width" th:text="${i}"></a
</span>
<span th:unless="${i == curpage}">
<a href="/listEmployee/${i}" class="btn btn-danger custom-width" th:text="${i}"></a> 
</span>
</span>
</div>

insira a descrição da imagem aqui

Tứ Nguyễn Duy
fonte
1

Use th:switchcomoif-else

<span th:switch="${isThisTrue}">
  <i th:case="true" class="fas fa-check green-text"></i>
  <i th:case="false" class="fas fa-times red-text"></i>
</span>

Use th:switchcomoswitch

<span th:switch="${fruit}">
  <i th:case="Apple" class="fas fa-check red-text"></i>
  <i th:case="Orange" class="fas fa-times orange-text"></i>
  <i th:case="*" class="fas fa-times yellow-text"></i>
</span>
Yatendra Goel
fonte