Jak zrobić if-else w Thymeleaf?

135

Jak najlepiej zrobić coś prostego if- elsew Thymeleaf?

Chcę osiągnąć w Thymeleaf taki sam efekt jak

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

w JSTL.

Co doszedłem do tej pory:

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

Nie chcę oceniać potentially_complex_expressiondwa razy. Dlatego wprowadziłem zmienną lokalną condition. Nadal nie lubię używać obu th:if="${condition}i th:unless="${condition}".

Ważną rzeczą jest to, że używam dwóch różnych tagów HTML: powiedzmy h2i span.

Czy możesz zaproponować lepszy sposób, aby to osiągnąć?

Maciej Ziarko
źródło

Odpowiedzi:

211

Thymeleaf ma odpowiednik <c:choose>i <c:when>: the th:switchi th:caseatrybuty wprowadzone w Thymeleaf 2.0.

Działają zgodnie z oczekiwaniami, używając *dla przypadku domyślnego:

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

Zobacz to, aby uzyskać szybkie wyjaśnienie składni (lub samouczki Thymeleaf).

Zastrzeżenie : Zgodnie z wymogami reguł StackOverflow jestem autorem Thymeleaf.

Daniel Fernández
źródło
ok, ale… jak wywołać javascript na podstawie typu klienta (np. anonimowy lub zalogowany) ...
Lucky
1
Zobacz rozdział dotyczący „wstawiania tekstu”, w szczególności sekcję „wstawianie w JavaScript” w samouczku „Korzystanie z Thymeleaf” na stronie thymeleaf.org/documentation.html
Daniel Fernández,
I jak mogę to zrobić: włączyć wartość iterator.index? Chcę zrobić zestaw przypadków, gdy wartość jest <5 i przełączyć się na wielkość domyślną, jeśli wartość jest> 5
Loser Coder
@ DanielFernández: czy możesz mi pomóc ze stackoverflow.com/questions/48499723/… . Nie mogłem oznaczyć Cię bezpośrednio w pytaniu. Naprawdę utknąłem.
molo
101

Wypróbowałem ten kod, aby dowiedzieć się, czy klient jest zalogowany, czy anonimowy. Użyłem wyrażeń warunkowych th:ifi th:unless. Całkiem prosty sposób na zrobienie tego.

<!-- 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>
Szczęściarz
źródło
5
To nie odpowiada na pytanie OP, ponieważ chodziło o unikanie powielania złożonych wyrażeń. I podobnie jak inne rozwiązania, łamie to ideę „naturalnych szablonów”, która jest głównym punktem sprzedaży Thymeleaf. Nie jestem pewien, co z tym zrobić, ale chciałem tylko zwrócić na to uwagę na wypadek, gdyby ktoś miał odpowiedź.
Stephen Harrison
@Lucky to daje mi błąd EL1007E: (pozycja 0): Nie można znaleźć właściwości lub pola „Status”
Jesse
@Jackie W powyższym przykładzie klient jest obiektem, a anonimowy jest polem boolowskim w klasie Customer. Upewnij się, że obiekt nie ma wartości NULL, a nazwa pola jest poprawna.
Lucky
26

Oprócz Daniela Fernándeza chciałbym podzielić się moim przykładem dotyczącym bezpieczeństwa.

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

Oto złożone wyrażenie z mieszanymi obiektami narzędziowymi „uwierzytelnianie” i „autoryzacja”, które dają wynik „prawda / fałsz” dla kodu szablonu tymeleaf.

Obiekty narzędziowe „uwierzytelnianie” i „autoryzacja” pochodzą z biblioteki thymeleaf extras springsecurity3 . Gdy obiekt „authentication” nie jest dostępny LUB authorisation.expression („isAuthenticated ()”) przyjmuje wartość „false”, wyrażenie zwraca $ {false}, w przeciwnym razie $ {true}.

mdlejszy
źródło
To dobra wskazówka, ale pamiętaj, że możesz używać truei falseliterałów - nie musisz używać do nich wyrażeń podstawiania zmiennych. Zobacz także odpowiedź Yatendry .
Garret Wilson
19

Możesz użyć

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

Przykład:

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

Może to być przydatne dla nowych osób zadających to samo pytanie.

Jad B.
źródło
12

Inne rozwiązanie - możesz użyć zmiennej lokalnej:

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

Więcej o zmiennych lokalnych:
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#local-variables

jareks
źródło
Myślę, że dodałeś dodatkowy znak „=” w swoim kodzie. Sprawdź to ponownie i popraw, jeśli mam rację.
Lucky
Moim zdaniem kod jest w porządku. Nie wiem, który dodatkowy znak „=” masz na myśli.
jareks
Tak, kod jest w porządku. Przepraszam, pomyliłem to z tym, th:eachgdzie wyrażenie ma :zamiast=
Lucky
Ale ta odpowiedź jest bardzo bliska mojemu rozwiązaniu. Robiąc th: z wyrazem twarzy wydaje mi się zbędny. Zasadniczo to rozwiązanie wykorzystuje instrukcje warunkowe th: if i th: chyba.
Lucky
Myślę, że to nie jest zbędne. Jeśli użyjesz tylko th: if i th: chyba że złożone wyrażenie zostanie wykonane dwukrotnie ...
jareks
9

W prostszym przypadku (gdy tagi html są takie same):

<h2 th:text="${potentially_complex_expression} ? 'Hello' : 'Something else'">/h2>
Grigorij Kislin
źródło
Czy wiesz, jak dodać tłumaczenia słów „Hello” i „Something else” w tym wyrażeniu?
Laura
@Laura Możesz użyć internacjonalizacji i załadować tłumaczenia na różne języki w oparciu o lokalizację z pliku właściwości. Zobacz lookok.wordpress.com/tag/internationalization , marcelustrojahn.com/2016/12/…
Lucky
7

Innym rozwiązaniem jest użycie po prostu notodwrotnej negacji:

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

Jak wyjaśniono w dokumentacji , jest to to samo, co używanie th:unless. Jak wyjaśniły inne odpowiedzi:

Ponadto, th:ifma odwrotną atrybut th:unless, który moglibyśmy korzystać w poprzednim przykładzie , zamiast przy użyciu nie wewnątrz wyrażenia OGNL

Używanie notrównież działa, ale IMHO jest bardziej czytelne w użyciu th:unlesszamiast negowania warunku za pomocą not.

Pau
źródło
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
źródło
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>

wprowadź opis obrazu tutaj

Tứ Nguyễn Duy
źródło
1

Użyj th:switchjakoif-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>

Użyj th:switchjakoswitch

<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
źródło