在JSF中伪造递归

时间:2013-09-19 14:28:41

标签: jsf recursion tree

我正在尝试在JSF中显示一个树而不对我要显示的树的深度进行硬编码。也许对于一种配置我只想显示叶子,也许对于另一种配置我想要显示由它们上面的节点分组的叶子等等。所以对于一种配置,它可能是:

  • 问题1
  • 问题2
  • 问题3
  • 问题4

对于另一种配置,相同的底层数据结构可能会产生:

  • 第1类:
    • 问题1
    • 问题2

  • 第2类:
    • 问题3

  • 第3类:
    • 问题4

使用假设的第三种配置按超级类别等分组类别

我尝试制作一个复合组件,如果节点有更多子节点,则会递归调用自身。我是通过<ui:fragment rendered="#{node.hasChildren}">完成的,并且 - 惊喜! - 这导致无限循环和堆栈溢出。

该项目已经安装了PrimeFaces,因此我正在关注PrimeFaces TreeTreeNode。但那感觉不对;我不希望树节点在用户界面中可扩展。我希望一切都能完全扩展。我没有太深入这个兔子洞,所以我怀疑可能有一种方法可以通过Tree实现这一点,但感觉我正在反对它的构建要做的事情。

这个问题的好处是什么?

<小时/> 编辑:我正在尝试使用&lt; tree&gt;和&lt; treeNode&gt;,但它不起作用。我的代码如下所示:

<p:tree value="#{cc.attrs.classification}" var="child">
    <p:treeNode>
        <ui:fragment rendered="#{child.childCount > 0}">
            [do node stuff]
        </ui:fragment>
        <ui:fragment rendered="#{child.childCount == 0}">
            [do leaf stuff]
        </ui:fragment>
    </p:treeNode>
</p:tree>

...其中classification实现了TreeNode接口。这会导致控制台出错,抱怨child的类型为String,因此无法执行我要求的任何有趣的事情。我做错了什么?

2 个答案:

答案 0 :(得分:4)

  

我尝试制作一个复合组件,如果节点有更多子节点,则会递归调用自身。我这样做了 - 惊喜! - 这导致无限循环和堆栈溢出。

失败是因为在构建JSF组件树期间未评估rendered属性,而是仅在生成HTML输出期间。您基本上需要JSTL <c:if>而不是<some:component rendered>It runs during building the JSF component tree,所以你最终无限包括复合本身。


  

该项目已经安装了PrimeFaces,所以我正在查看PrimeFaces Tree和TreeNode。但那感觉不对;我不希望树节点在用户界面中可扩展。我希望一切都能完全扩展。

JSF实用程序库OmniFaces具有您正在寻找的组件<o:tree>。该组件本身不会生成任何HTML标记,因此您可以自由地按照自己的方式声明HTML / JSF标记,也可以用于特定的深度级别。

Here's the showcase example。请注意页面底部的链接,它们指向源代码,这可能是有用/有趣的学习练习。你在开发复合材料时可能最初的想法并不是那么简单(毕竟不是the right tool for the job)。

至于区分叶节点,<o:tree>提供了如下可能性:

<o:tree value="#{bean.tree}" var="item" varNode="node">
    <o:treeNode>
        <o:treeNodeItem>
            <ui:fragment rendered="#{not node.leaf}">
                ...
            </ui:fragment>
            <ui:fragment rendered="#{node.leaf}">
                ...
            </ui:fragment>
            <o:treeInsertChildren />
        </o:treeNodeItem>
    </o:treeNode>
</o:tree>

答案 1 :(得分:3)

好。由于您可以从ManagedBean管理树结构,因此您可以在Java中进行递归,只需渲染树。

上周我做到了。在prerenderview期间,我使用递归方法初始化树,例如:

 <p:tree value="#{bean.tree}" var="node" selection="#{bean.property}" >   
   <p:treeNode>  
     <h:outputText value="#{node}" /> 
   </p:treeNode>
 </p:tree>

希望它有所帮助!