Как сделать if-else в Тимелеафе?

132

Как лучше всего сделать простой if- elseв Тимелеафе?

Я хочу добиться в Thymeleaf того же эффекта, что и

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

в JSTL.

Что я понял до сих пор:

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

Не хочу оценивать potentially_complex_expressionдважды. Вот почему я ввел локальную переменную condition. Тем не менее, я не люблю использовать оба th:if="${condition}и th:unless="${condition}".

Важно то, что я использую два разных HTML-тега: скажем h2и span.

Вы можете предложить лучший способ достичь этого?

Мацей Зярко
источник

Ответы:

208

Thymeleaf имеет эквивалент атрибутов <c:choose>and <c:when>: the th:switchи, th:caseпредставленных в Thymeleaf 2.0.

Они работают так, как вы ожидаете, используя *для случая по умолчанию:

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

См. Это для быстрого объяснения синтаксиса (или руководств по Thymeleaf).

Отказ от ответственности : согласно правилам StackOverflow, я являюсь автором Thymeleaf.

Даниэль Фернандес
источник
хорошо, но .. как мне вызвать javascript в зависимости от типа клиента (то есть анонимный или вошедший в систему) ...
Lucky
1
См. Главу «Встраивание текста», в частности раздел «Встраивание JavaScript» в учебнике «Использование Thymeleaf» на сайте thymeleaf.org/documentation.html
Даниэль Фернандес
И как я могу сделать это: включить значение iterator.index? Я хочу сделать набор случаев, когда значение <5, и переключиться на случай по умолчанию, если значение> 5
Loser Coder
@ DanielFernández: не могли бы вы помочь мне с stackoverflow.com/questions/48499723/… . Я не мог напрямую отметить тебя в вопросе. Действительно застрял.
причал
98

Я попробовал этот код, чтобы узнать, вошел ли клиент в систему или анонимен. Я сделал с помощью th:ifи th:unlessусловных выражений. Довольно простой способ сделать это.

<!-- 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>
Счастливый
источник
5
Это не отвечает на вопрос ОП, потому что речь идет об избежании дублирования сложных выражений. И, как и другие решения, это ломает идею «естественных шаблонов», которая является основным преимуществом Thymeleaf. Сам не уверен, что с этим делать, но просто хотел указать на это, если у кого-то есть ответ.
Стивен Харрисон
@ Lucky, это дает мне ошибку EL1007E: (pos 0): свойство или поле 'Status' не могут быть найдены
Джесси
@Jackie В приведенном выше примере клиент - это объект, а анонимный - это логическое поле в классе Customer. Убедитесь, что ваш объект не равен нулю, а имя поля правильное.
Lucky
25

Я хотел бы поделиться своим примером, связанным с безопасностью, в дополнение к Даниэлю Фернандесу.

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

Вот сложное выражение со смешанными служебными объектами «аутентификация» и «авторизация», которое дает результат «истина / ложь» для кода шаблона тимелеафа.

Служебные объекты «аутентификация» и «авторизация» взяты из библиотеки thmeleaf extras springsecurity3 . Когда объект «аутентификации» недоступен ИЛИ authorization.expression ('isAuthenticated ()') оценивается как «false», выражение возвращает $ {false}, в противном случае - $ {true}.

blandger
источник
19

Ты можешь использовать

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

Пример:

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

Это может быть полезно для новых людей, задающих тот же вопрос.

Джад Б.
источник
12

Другое решение - вы можете использовать локальную переменную:

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

Подробнее о локальных переменных:
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#local-variables

jareks
источник
Я думаю, вы добавили в свой код дополнительный знак "=". Пожалуйста, проверьте его еще раз и исправьте, если я прав.
Удачливый,
На мой взгляд, код в порядке. Я не знаю, какой дополнительный знак "=" вы имеете в виду.
jareks
Да, код в порядке. Извините, я перепутал это с тем, th:eachгде :вместо выражения=
Lucky
Но этот ответ очень близок к моему решению. При выполнении th: with выражение кажется мне излишним. В основном это решение использует условные операторы th: if и th: except.
Удачливый
Думаю, это не лишнее. Если вы используете только th: if и th: если комплексное выражение не будет выполнено дважды ...
jareks
9

В более простом случае (когда теги html совпадают):

<h2 th:text="${potentially_complex_expression} ? 'Hello' : 'Something else'">/h2>
Григорий Кислин
источник
Вы знаете, как добавить к этому выражению переводы «Hello» и «Something else»?
Лаура
@Laura Вы можете использовать интернационализацию и загружать переводы на разные языки в зависимости от местоположения из файла свойств. См. Looksok.wordpress.com/tag/internationalization , marcelustrojahn.com/2016/12/…
Lucky
7

Другое решение просто использовать notдля получения противоположного отрицания:

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

Как объясняется в документации , это то же самое, что и использование th:unless. Как объяснили другие ответы:

Также th:ifимеется обратный атрибут, th:unlessкоторый мы могли бы использовать в предыдущем примере вместо использования not внутри выражения OGNL.

Использование notтакже работает, но, IMHO, его удобнее использовать th:unlessвместо отрицания условия с помощью not.

Pau
источник
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>
Дарья Ю
источник
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>

введите описание изображения здесь

То Нгуен Дуй
источник
1

Использовать th:switchкакif-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>

Использовать th:switchкакswitch

<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>
Ятендра Гоэль
источник