Thymeleaf th:each中JavaScript变量取值异常问题及解决咨询
问题描述
尝试用Thymeleaf的th:each标签构建表格,同时实现表格整行点击跳转功能,代码如下:
<table> <th:block th:each='user : ${list}'> <script th:inline="javascript"> var userid = [[${user.id}]]; </script> <tr onclick="location.href='user?id='+userid"> <td th:text="${user.firstName}"></td> <td th:text="${user.lastName}"></td> </tr> </th:block> </table>
但发现JavaScript变量userid始终指向最后一次循环的取值,而非该行创建时的对应值,求解决方法或其他实现方案。
解决方案
方案一:直接在onclick中嵌入Thymeleaf变量(最简洁)
不需要额外的JS变量,直接把用户ID通过Thymeleaf拼接到onclick的跳转链接里,彻底避免变量作用域问题:
<table> <tr th:each="user : ${list}" th:onclick="|location.href='user?id=' + ${user.id}|"> <td th:text="${user.firstName}"></td> <td th:text="${user.lastName}"></td> </tr> </table>
这里用了Thymeleaf的文本内联语法|...|,可以直接把变量和字符串拼接,比手动拼接更清晰。
方案二:用自定义属性+事件委托(更优雅)
如果不想在HTML里写大量JS逻辑,可以给每行绑定自定义属性存储ID,然后通过事件委托统一处理点击事件:
<table id="userTable"> <tr th:each="user : ${list}" th:data-user-id="${user.id}"> <td th:text="${user.firstName}"></td> <td th:text="${user.lastName}"></td> </tr> </table> <script> document.getElementById('userTable').addEventListener('click', function(e) { const tr = e.target.closest('tr'); if (tr) { const userId = tr.dataset.userId; location.href = `user?id=${userId}`; } }); </script>
这种方式把JS逻辑和HTML结构分离,维护性更好,尤其适合表格行数较多的场景。
方案三:修复原代码的变量作用域问题
原代码的问题在于var声明的变量没有块级作用域,每次循环都会覆盖同一个userid变量,最终所有行都指向最后一次循环的值。可以用以下两种方式修复:
用let声明块级作用域变量:
<table> <th:block th:each='user : ${list}'> <script th:inline="javascript"> let userid = [[${user.id}]]; // 用let替代var,创建块级作用域 </script> <tr onclick="location.href='user?id='+userid"> <td th:text="${user.firstName}"></td> <td th:text="${user.lastName}"></td> </tr> </th:block> </table>
用立即执行函数创建独立作用域:
<table> <th:block th:each='user : ${list}'> <script th:inline="javascript"> (function() { var userid = [[${user.id}]]; document.currentScript.nextElementSibling.onclick = function() { location.href = 'user?id=' + userid; }; })(); </script> <tr> <td th:text="${user.firstName}"></td> <td th:text="${user.lastName}"></td> </tr> </th:block> </table>
不过这种方式比前两种方案繁琐,不推荐作为首选。
内容的提问来源于stack exchange,提问作者asd
相关产品推荐
相关产品推荐

