列表頁每行按鈕需調用 JS 函數並傳遞當前行主鍵 ID 與操作類型,Thymeleaf 模板引擎中動態生成內聯 JS 調用。
@GetMapping("/list")
public String list(PageUtil<CliCorp> page, CliCorpQuery query, Model model) {
PageUtil<CliCorp> corps = corpClientService.queryByPage(page, query);
model.addAttribute("corps", corps);
return "corp/list";
}
<table>
<tr th:each="corp : ${corps.contents}">
<td><span th:text="${corp.name}"></span></td>
<td><span th:text="${corp.creditCode}"></span></td>
<!-- 更多字段 -->
<td>
<button type="button"
th:onclick="'javascript:check(' + ${corp.id} + ', 2)' ">審核</button>
<button type="button"
th:onclick="'javascript:check(' + ${corp.id} + ', 3)' ">拒絕</button>
</td>
</tr>
</table>
th:onclick:設置元素 onclick 屬性'javascript:check(' + ${corp.id} + ', 2)':Thymeleaf 表達式拼接字符串,${corp.id} 自動轉為字符串onclick="javascript:check(1001, 2)"function check(id, status) {
$.ajax({
type: "POST",
url: "/admin/corp/check",
data: { id: id, status: status },
success: function(res) {
if (res.success) {
location.href = "/admin/corp/list"; // 刷新列表
} else {
alert("操作失敗: " + res.msg);
}
},
error: function() { alert("網絡異常"); }
});
}
@PostMapping("/check")
@ResponseBody
public R check(@RequestParam Long id, @RequestParam Integer status) {
try {
corpClientService.audit(id, status); // 2=通過, 3=拒絕
return R.ok("操作成功");
} catch (Exception e) {
log.error("審核失敗", e);
return R.error("審核異常");
}
}
th:onclick=\"'check(\\' + ${corp.name} + '\\')'\"(單雙引號交替)<button type="button" class="audit-btn"
data-id="${corp.id}" data-status="2">審核</button>
// JS 一處綁定
$('#corpTable').on('click', '.audit-btn', function() {
check($(this).data('id'), $(this).data('status'));
});
優勢:模板乾淨、CSP 友好、參數類型安全、便於批量綁定
<script th:inline="javascript">
const corpIds = [[${corps.contents.![id]}]]; // 導出數組
</script>
| 錯誤寫法 | 問題 | 修正 |
|---|---|---|
th:onclick="check(${corp.id})" | 缺少 javascript: 協議,Thymeleaf 不輸出 | 加前綴或改用 data-* |
th:onclick="'check(' + ${corp.name} + ')'" | 字符串參數無引號 → JS 語法錯誤 | 'check(\\'' + ${corp.name} + '\\')' |
th:onclick="@{/check(id=${corp.id})}" | @{} 生成 URL,非 JS 調用 | 改用 data-* + AJAX |