FreeMarker函数与宏的比较

15

大家好,freemarker专家们

我知道freemarker的函数和宏之间的区别在于宏可以输出到输出流中,但不能返回值,而函数可以返回值但不能输出到输出流中。

问题是我需要同时输出到输出流中并返回值:

我正在使用freemarker进行递归树遍历,因此我需要一个递归调用的宏。随着树的遍历,我既需要将节点信息打印到输出中,又需要计算并返回有关已遍历节点的统计信息(例如已遍历节点某个属性的总和)。

如果我使用递归调用的宏,我可以将节点信息打印出来,但无法将统计信息返回给调用实体。

如果我使用递归调用的函数,我可以返回统计信息,但无法将节点信息打印到输出流中。

其中一种解决方法是两次遍历树,一次打印节点信息,另一次收集统计信息,但我不想采用这种不太优美的解决方案。

有人能提出更好的解决方案吗?

谢谢!

2个回答

2

或者你甚至可以使用全局变量作为存储统计数据的方式:

<#global stats = [] />

<#-- then when you call your function -->
<#assign = method() />

<#function method param = "">
    <#-- do something and before you return you push the stats to the global variable, if you choose my approach of "merging" sequences, be careful that you wrap the new stats item also in a sequence or it will fail miserably =) -->
    <#global stats = stats + [{"statvar1": 10, "statvar2": 30}] />

    <#return whateveryoulike />
</#function>

1

您可以将统计数据存储在非#local变量中。就像在宏中使用<#assign treeStats = ...>,然后在调用站点上:

<#import my="myutils.ftl">
...
<@my.tree input />
<#assign stats = my.treeStats /> <#-- or whatever you want with my.treeStats -->

是的,这很尴尬,但FreeMarker没有out-params来返回第二个结果。实际上,你可以通过循环变量来进行一些技巧性操作,但这可能会太过混乱,而且如果你真的需要一个主体,就不能使用这个技巧:

<@my.tree input; res><#assign stats = res></@>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接