如何在Freemarker模板中使用s:iterator的status生成唯一ID?
解决FTL文件中生成动态唯一ID的问题
这个问题我之前处理过,核心原因是Struts的OGNL上下文和FreeMarker的上下文是相互独立的——你在<s:iterator>里的#userStatus是Struts的OGNL变量,但<s:include>引入的FTL文件是由FreeMarker引擎解析的,它不认识Struts的%{...}表达式语法,所以直接用id="%{#userStatus.index}"自然不会生效。
给你两个可行的解决方案:
方案一:传递单个索引参数到FTL
在JSP的<s:include>标签里,通过<s:param>把迭代器的索引值传递给FTL文件:
<s:iterator value="list" status="userStatus"> <!-- 其他JSP内容 --> <s:include value="relation.ftl"> <!-- 把当前迭代的索引作为参数传入FTL --> <s:param name="itemIndex" value="#userStatus.index" /> </s:include> <!-- 其他JSP内容 --> </s:iterator>
然后在relation.ftl中,用FreeMarker自身的表达式语法${}来获取这个参数,生成唯一ID:
<!-- 用FTL的表达式生成动态ID --> <div id="relation-item-${itemIndex}"> <!-- 你的FTL内容 --> </div>
方案二:传递整个迭代状态对象到FTL
如果你需要用到迭代状态的其他属性(比如判断是否是第一个/最后一个元素first/last,或者计数count),可以直接把整个userStatus对象传递进去:
<s:iterator value="list" status="userStatus"> <!-- 其他JSP内容 --> <s:include value="relation.ftl"> <s:param name="userStatus" value="#userStatus" /> </s:include> <!-- 其他JSP内容 --> </s:iterator>
在relation.ftl中就可以直接访问状态对象的所有属性了:
<div id="relation-item-${userStatus.index}"> <!-- 示例:判断是否为第一个元素 --> <#if userStatus.first> <p>这是第一个元素</p> </#if> <!-- 你的FTL内容 --> </div>
关键提醒
一定要注意区分Struts的OGNL表达式(%{...})和FreeMarker的表达式(${})——FTL文件里只能用FreeMarker的语法来访问变量,所以必须通过<s:param>把需要的Struts上下文变量传递到FTL的上下文里才行。
内容的提问来源于stack exchange,提问作者Dat Nguyen
相关产品推荐
相关产品推荐

