Thymeleaf内联JavaScript如何使用动态变量调用message.properties
问题原因
Thymeleaf的所有模板表达式(包括#{}国际化取值表达式)都是服务端渲染阶段执行的,执行时机远早于浏览器端JavaScript代码的运行,根本无法访问到JS层面定义的客户端变量。
你写的[[#{'message.data.'+ data}]]在服务端解析时,无法识别JS上下文里的data变量,最终拼接出的国际化key完全不符合预期,找不到对应配置时Thymeleaf就会输出??key_语言区域标识??格式的错误提示,你看到的message_de_DE就代表当前页面启用的是德语(德国)语言环境。
正确实现方案
不要尝试在服务端的Thymeleaf表达式里拼接客户端动态变量,通用做法是提前在服务端渲染阶段,把所有需要用到的同前缀国际化配置预生成一个JS键值对对象,客户端运行时直接用动态key从对象中取值即可:
// 服务端渲染时批量注入message.data.前缀下的所有国际化配置,生成JS对象 const dataMessageMap = { /*[# th:each="item : ${#messages.getMessagesWithKeyStartingWith('message.data.')}"]*/ /*[# th:utext="'"' + ${item.key.substring('message.data.'.length())} + '": "' + ${#strings.escapeJavaScript(item.value)} + '",'"]*/ /*[/#]*/ }; // 客户端动态取值逻辑 let data = data[i]; // 直接从预生成的map中取对应文案,可配置兜底文案防止key不存在的异常 let message = dataMessageMap[data] ?? '默认提示';
- 上述代码在服务端渲染时,会自动遍历所有
message.data.开头的国际化配置,把key的后缀部分作为JS对象的键,对应语言的翻译值做JS转义后作为对象的值,最终生成一个可直接在前端使用的普通JS对象 - 等页面加载完成、JS代码执行时,不管
data变量是什么动态值,都可以直接从预生成的对象中读取对应国际化文案,完全不存在跨执行时序的问题 - 取值时加空值兜底逻辑,可以避免动态值不在配置范围内时出现undefined的前端异常
#messages.getMessagesWithKeyStartingWith是Thymeleaf内置的消息工具方法,不需要额外编写后端接口,只要是项目里配置的国际化资源都可以直接通过该方法按前缀匹配获取
内容的提问来源于stack exchange,提问作者TheCakeIsALie
相关产品推荐
相关产品推荐

