浏览 2476 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-12-22
最后修改:2010-12-22
比如下面这个tag嵌套,是一个对ext grid的封装: <g:list id="gridobj" width="100%" checkbox="true" keyField="NEW_ID" splitInfo="splitParam" rowdbclick="rowdbclick" contentHeightOffset="-100"> <g:query> <g:queryItem label="名称" name="NEW_TITLE" /> <g:queryItem label="时间(起)" itemType="datefield" name="NEW_DATE1" /> <g:queryItem label="时间(止)" itemType="datefield" name="NEW_DATE2" /> </g:query> <g:field fieldname="NEW_ID" header="编号" width="80" hidden="true" /> <g:field fieldname="STATUS" header="图片" width="35" renderer="statusHandler"/> <g:field fieldname="NEW_TITLE" header="项目名称" width="230" /> <g:field fieldname="NEW_SUMMARY" header="新闻摘要" width="300" renderer="summaryHandler"/> <g:field fieldname="NEW_DATE" header="时间" width="85" renderer="dateformat" /> <g:field fieldname="IMAGE_URL" header="新闻路径" width="100" hidden="true"/> </g:list> 但是freemarker macro没有这个能力,在宏的嵌套body中,只能在宏中通过<#nested>来访问标签之间的文本,或者直接用参数传过去,而不能在tag之间设置tag的参数,宏的局部变量对宏tag之间的body也是隐藏的 为此我开发了两个directive ExposeDirective ParamDirective ExposeDirective实现了把当前宏的macroContext导出到全局变量,同是如果发现自己被宏调用嵌套,则创建一个变量保存父宏的macroContext,达到访问父宏上下文的目的 Macro.Context mc = env.getCurrentMacroContext(); if (mc == null) { throw new TemplateException("macro context not found,this directive must be call in macro", env); } List stack = DirectiveHelper.getElementStack(env); Object macroCall = null, parentMacroCall = null; for (int i = stack.size() - 1; i > -1; i--) { //遍历当前运行时堆栈,找到当前宏的UnifiedCall if (stack.get(i) instanceof Macro) { Object call = stack.get(i - 1); if (macroCall == null) { macroCall = call; } else { parentMacroCall = call; break; } } } DirectiveHelper.exposeMacroContext(env, macroCall, mc);//暴露当前宏local变量上下文到全局上下文 if (parentMacroCall == null) return; Macro.Context parentMc = (Macro.Context) DirectiveHelper.getMacroContext(env, parentMacroCall);//获取父宏上下文 if (parentMc != null) mc.setLocalVar(DirectiveHelper.getParam(params, "parent", "parent"), parentMc.getLocals());//在当前宏上下文中保存一个叫parent的变量,值为父宏的local变量 ParamDirective则根据当前的调用堆栈找到macroContext,从而可以访问到宏的局部变量,实现了宏的嵌套使用,并且支持复杂的参数设置 请看例子: 设置变量 <#macro outer name="ozn" age="27" sex="boy"> <@expose/> <#nested> </#macro> <#macro inner parent={}> <@expose/> <@param name="parent.name" value="cici"/> ${parent.name} </#macro> <@outer><@inner/></@> 使用body来设置变量值 <@param name="addr.area">${addr.country}</@> 删除变量 <#macro outer name="ozn" age="27" sex="boy"> <@expose/> <#nested> </#macro> <#macro inner parent={}> <@expose/> <@param name="parent.name" action="remove"/> ${parent?keys?size} </#macro> <@outer><@inner/></@> 添加变量 <#macro hello name=["ozn","cici"]> <@expose/> <#nested> ${name?size} </#macro> <@hello><@param name="name" value="me" action="add"/></@> 更多例子请看代码里面的testCase 另附上覆盖率测试图 有任何问题,请不吝赐教 代码托管于: http://code.google.com/p/freemarker-sweet/ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |