Grails中如何根据当前语言动态访问多语言字段?
解决方案
方法一:GSP中直接动态访问Map键值
你通过executeQuery返回的是Map集合,Groovy支持通过字符串拼接的键名来动态访问Map属性,直接修改GSP代码即可:
<g:each in="${family}" status="index" var="record"> ${record?."name_${lang}"} </g:each>
也可以用Map的get方法实现相同效果:
<g:each in="${family}" status="index" var="record"> ${record?.get("name_${lang}")} </g:each>
你之前尝试的${record?.name_lang}不符合GSP表达式语法,所以无法生效,而字符串拼接的动态键访问是Groovy原生支持的写法。
方法二:Domain类中新增辅助方法(更易维护)
在Family类里添加一个根据语言返回对应名称的方法,让业务逻辑更内聚:
class Family { String name_en String name_fr String getNameForLang(String lang) { // 默认返回英文,可根据需求调整默认值 lang == 'fr' ? name_fr : name_en } }
控制器查询时直接返回Domain对象(无需转Map):
def family = Family.list()
GSP中直接调用该方法:
<g:each in="${family}" status="index" var="record"> ${record?.getNameForLang(lang)} </g:each>
方法三:控制器层提前处理数据
如果希望GSP逻辑更简洁,可以在控制器中提前根据当前语言组装好数据:
def locale = org.springframework.web.servlet.support.RequestContextUtils.getLocale(request) def lang = locale.language def family = Family.executeQuery("select new Map(name_en as name_en, name_fr as name_fr) from Family") // 转换为仅包含当前语言名称的集合 def familyWithCurrentLang = family.collect { [name: it."name_${lang}"] } // 将处理后的集合传递给GSP [family: familyWithCurrentLang]
GSP中直接访问简化后的属性:
<g:each in="${family}" status="index" var="record"> ${record?.name} </g:each>
内容的提问来源于stack exchange,提问作者NiBE
相关产品推荐
相关产品推荐

