如何在Thymeleaf中使用if-else语句?

170

在Thymeleaf中,如何用最简单的方式实现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标签:假设是h2span

你能建议更好的方法来实现吗?

14个回答

256

Thymeleaf有一个等同于<c:choose><c:when>的功能:在Thymeleaf 2.0中引入的th:switchth:case属性。

它们的工作方式与您预期的相同,使用*表示默认情况:

<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
请参阅位于http://www.thymeleaf.org/documentation.html的“Thymeleaf使用教程”中关于“文本内联”的章节,特别是“JavaScript内联”部分。 - Daniel Fernández
我怎样才能在迭代器的索引值上使用th:switch呢?我想在值小于5时执行一系列case,如果值大于5则切换到默认case。 - Loser Coder
1
@DanielFernández:你能帮我看看这个问题吗?https://dev59.com/XFYM5IYBdhLWcg3wrRuC。我无法直接在问题上标记你。真的卡住了。 - jetty
原始问题是关于一个布尔条件的。你如何使用switch来实现这个呢?你会把第一个case设置为th:case="true"吗? - GreenGiant

134

我尝试使用 th:ifth: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>

12
这并没有回答提问者的问题,因为他的问题是关于避免重复复杂表达式的。和其他解决方案一样,这也破坏了“自然模板”的概念,而这正是Thymeleaf的一个主要卖点。我自己也不确定该怎么做,但只是想指出这一点,以防有人有答案。 - Stephen Harrison
@Lucky 这给我一个错误 EL1007E:(pos 0): 找不到属性或字段 'Status' - JayC
@Jackie 在上面的例子中,customer是一个对象,anonymous是Customer类中的布尔字段。确保您的对象不为空且字段名称正确。 - Lucky

34

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

这是一个复杂的表达式,其中混合了“认证”和“授权”实用对象,为thymeleaf模板代码生成“true/false”结果。

“认证”和“授权”实用对象来自于thymeleaf extras springsecurity3库。当“认证”对象不可用或授权表达式('isAuthenticated()')的评估结果为“false”时,表达式返回$ {false},否则返回$ {true}。


这是个不错的提示,但请注意你可以使用truefalse字面值而不必使用变量替换表达式。另请参阅Yatendra的答案 - Garret Wilson

22

您可以使用

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

例子:

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

对于询问同样问题的新手来说,这可能是有用的。


16

我认为你在代码中多加了一个"="号。请再次验证并在我正确时进行更正。 - Lucky
在我看来,代码没问题。我不知道你指的是哪个多余的“=”符号。 - jareks
代码没问题。抱歉,我把它和 th:each 混淆了,那里的表达式使用的是 : 而不是 = - Lucky
但是这个答案非常接近我的解决方案。在执行th:with表达式时,我觉得有些多余。基本上,这个解决方案使用了th:if和th:unless条件语句。 - Lucky
我认为这不是多余的。如果只使用th:if和th:unless,复杂表达式将被执行两次... - jareks
显示剩余2条评论

11
在更简单的情况下(即HTML标签相同的情况下):
<h2 th:text="${potentially_complex_expression} ? 'Hello' : 'Something else'">/h2>

你知道如何在这个表达式中添加“Hello”和“Something else”的翻译吗? - Laura
@Laura,你可以使用国际化并从属性文件中加载不同语言的翻译,根据地理位置进行选择。请参考 https://looksok.wordpress.com/tag/internationalization/ 和 http://www.marcelustrojahn.com/2016/12/springboot-thymeleaf-i18n-internationalization/。 - Lucky
重要的是我使用了两个不同的HTML标签:比如说h2span - Egor Hans

11

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

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:if有一个相反的属性,th:unless,我们可以在前面的示例中使用th:unless代替在OGNL表达式中使用not

使用not也可以,但在我看来,使用th:unless而不是用not否定条件更易读。


1
这仍然会重复表达式,这正是OP试图避免的。 - Egor Hans

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>

2
<div th:switch="true"> 
    <div th:case="${condition}=='1'">answer1...</div>
    <div th:case="${condition}=='2'">answer2...</div>
    <div th:case="*">answer3...</div> 
</div>

1
嘿,感谢你的加入和贡献。在 StackOverflow 上,我们鼓励你解释答案,而不仅仅提供一个片段。 - f.khantsis
太棒了,兄弟!非常感谢你的绝妙技巧。简直就像魔法一样!这个答案应该排在首位,这才是真正的替代if-else条件的方法。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接