Thymeleaf Switch-Case中嵌入类与二级变量赋值问题求助
解决Thymeleaf的th:switch类嵌入与动态id问题
我来帮你搞定这两个Thymeleaf的问题,先从最容易解决的动态id语法错误说起,再梳理th:switch的结构问题。
1. 动态生成id属性的正确姿势
你现在用的$(workflow.id)是其他模板引擎的语法,Thymeleaf不识别这个!想要在属性里嵌入变量,有两种常用方法:
方法一:使用th:id属性+字符串拼接
直接用Thymeleaf的表达式语法拼接静态文本和变量,这是最标准的写法:
<!-- 传统字符串拼接 --> <tr th:case="null" th:id="'confirm_' + ${workflow.id} + '_row'"> <!-- Thymeleaf 3+支持的|简化拼接,可读性更强 --> <tr th:case="null" th:id="|confirm_${workflow.id}_row|">
你的确认按钮id也需要改成:
<td class="confirm" th:id="|confirm_${workflow.id}|">
方法二:内联表达式
如果你想保留原生的id属性写法,可以用[[${}]]内联变量,Thymeleaf会自动替换里面的变量值:
<tr th:case="null" id="confirm_[[${workflow.id}]]_row"> <!-- 确认按钮 --> <td class="confirm" id="confirm_[[${workflow.id}]]">
注意:内联默认是开启的,除非你在模板里手动关闭了(比如th:inline="none")。
2. 修复th:switch的结构问题
你当前的th:switch写法有两个致命问题,导致类无法生效:
- div不能直接包裹tr:HTML规范里,
<tr>必须放在<table>、<tbody>这类容器里,直接用div包tr会被浏览器自动修正DOM结构,导致th:switch逻辑失效。 - tr标签未闭合且结构混乱:你每个th:case只写了
<tr>开头,没闭合,而且后面的<td>都在tr外面,这完全不符合HTML结构规范。
正确的th:switch写法
把switch放在<tr>本身上,每个case对应完整的tr内容(或者只切换需要变化的部分):
场景1:不同状态的tr内容差异大
<tbody> <th:block th:each="workflow : ${workflows}"> <tr th:switch="${workflow.status}"> <!-- Accepted状态的完整tr --> <th:case="'Accepted'" class="accepted"> <td th:text="${workflow.name}">Test Name</td> <!-- 其他状态对应的td --> <!-- 确认按钮逻辑 --> <th:block th:if="${workflow.status} == null"> <td class="confirm" th:id="|confirm_${workflow.id}|"> <b>Confirm</b> </td> </th:block> </th:case> <!-- Declined状态 --> <th:case="'Declined'" class="declined"> <td th:text="${workflow.name}">Test Name</td> <!-- 对应Declined的内容 --> </th:case> <!-- 空状态(带动态id) --> <th:case="null" th:id="|confirm_${workflow.id}_row|"> <td th:text="${workflow.name}">Test Name</td> <td class="confirm" th:id="|confirm_${workflow.id}|"> <b>Confirm</b> </td> </th:case> <!-- 其他状态同理 --> </tr> </th:block> </tbody>
场景2:大部分内容重复,仅类或少量元素变化
如果不同状态的tr大部分内容一样,只需要切换类或者个别按钮,可以简化写法:
<tbody> <th:block th:each="workflow : ${workflows}"> <tr th:switch="${workflow.status}"> <!-- 公共内容,所有状态都显示 --> <td th:text="${workflow.name}">Test Name</td> <!-- ...其他公共td --> <!-- 根据状态设置tr的类 --> <th:case="'Accepted'" th:class="accepted"></th:case> <th:case="'Declined'" th:class="declined"></th:case> <th:case="'Pushed Back'" th:class="pushed-back"></th:case> <th:case="'Approved'" th:class="lock"></th:case> <th:case="null" th:id="|confirm_${workflow.id}_row|"></th:case> <!-- 确认按钮逻辑 --> <th:block th:if="${workflow.status} == null"> <td class="confirm" th:id="|confirm_${workflow.id}|"> <b>Confirm</b> </td> </th:block> </tr> </th:block> </tbody>
关于文本间嵌入变量的技巧
不管是在属性里还是文本内容里,Thymeleaf都能轻松混合静态文本和变量:
- 属性里用
|拼接最方便:th:id="|btn_${workflow.id}_submit|" - 文本内容里用内联表达式:
<p>Workflow [[${workflow.id}]] has been [[${workflow.status}]]</p> - 复杂拼接可以用
+:th:text="'Workflow ' + ${workflow.id} + ' status: ' + ${workflow.status}"
内容的提问来源于stack exchange,提问作者patrickjp93
相关产品推荐
相关产品推荐

