Jsf 我可以递归地将复合组件嵌套在其自身中吗?

Jsf 我可以递归地将复合组件嵌套在其自身中吗?,jsf,recursion,jsf-2,primefaces,composite-component,Jsf,Recursion,Jsf 2,Primefaces,Composite Component,我有包含自身的DTO(它是嵌套的) 我创建了复合组件,它可以递归地调用自身。我这样称呼它: <screen:my-dto-screen dto="#{myDTOBean.myDto}" /> 此异常在视图生成时发生。在视图生成期间,呈现的属性是未评估的。它只在视图渲染期间(以及在输入和命令组件上的应用请求值阶段)进行评估,但这只是一个故事。因此,您的方法将以无限递归循环结束,最终导致内存中的堆栈溢出 基本上,您希望在视图构建期间评估条件。因此,您需要在视图构建期间运行的标记/属性。

我有包含自身的DTO(它是嵌套的)

我创建了复合组件,它可以递归地调用自身。我这样称呼它:

<screen:my-dto-screen dto="#{myDTOBean.myDto}" />

此异常在视图生成时发生。在视图生成期间,
呈现的
属性是评估的。它只在视图渲染期间(以及在输入和命令组件上的应用请求值阶段)进行评估,但这只是一个故事。因此,您的方法将以无限递归循环结束,最终导致内存中的堆栈溢出

基本上,您希望在视图构建期间评估条件。因此,您需要在视图构建期间运行的标记/属性。其中之一是JSTL



但是,如果渲染时间属性提供了
#{cc.attrs.dto.nested}
值,则此操作不起作用,因此递归将不起作用。仅显示顶级组件。您正在寻找一种迭代方法。考虑查看现有的JSF树组件,如PrimeFrase.< /P> < P>此异常在视图生成时间期间发生。在视图生成期间,
呈现的
属性是评估的。它只在视图渲染期间(以及在输入和命令组件上的应用请求值阶段)进行评估,但这只是一个故事。因此,您的方法将以无限递归循环结束,最终导致内存中的堆栈溢出

基本上,您希望在视图构建期间评估条件。因此,您需要在视图构建期间运行的标记/属性。其中之一是JSTL



但是,如果渲染时间属性提供了
#{cc.attrs.dto.nested}
值,则此操作不起作用,因此递归将不起作用。仅显示顶级组件。您正在寻找一种迭代方法。考虑一下现有的JSF树组件,比如PrimeFo脸ts。

,我和OP有类似的问题,并设法用Frach来处理它,BaluSc也提供了下面的博客文章。以下所有内容均引自该来源,并全部归功于BalusC:

正如BalusC已经提到的,重要的是使用在视图构建期间运行的标记/属性,例如c:if和c:foreach。但是,下面的示例代码仍然会产生StackOverflower错误

<cc:interface>
    <cc:attribute name="node" type="com.example.SomeTreeModel" />
</cc:interface>
<cc:implementation>
    <c:if test="#{not empty cc.attrs.node.children}">
        <ul>
            <c:forEach items="#{cc.attrs.node.children}" var="node">
                <li>
                    #{node.data}
                    <my:tree node="#{node}" />
                </li>
            </c:forEach>
        </ul>
    </c:if>
</cc:implementation>
以及组件

<cc:interface componentType="treeComposite">
    <cc:attribute name="node" type="com.example.SomeTreeModel" />
</cc:interface>
<cc:implementation>
    <c:if test="#{not empty cc.node.children}">
        <ul>
            <c:forEach items="#{cc.node.children}" var="node" varStatus="loop">
                <li>
                    #{node.data}
                    <my:tree node="#{cc.parent.node.children[loop.index]}" />
                </li>
            </c:forEach>
        </ul>
    </c:if>
</cc:implementation>

  • #{node.data}

我遇到了与OP类似的问题,并设法与foreach一起解决了这个问题,下面的博文也是由BalusC提供的。以下所有内容均引自该来源,并全部归功于BalusC:

正如BalusC已经提到的,重要的是使用在视图构建期间运行的标记/属性,例如c:if和c:foreach。但是,下面的示例代码仍然会产生StackOverflower错误

<cc:interface>
    <cc:attribute name="node" type="com.example.SomeTreeModel" />
</cc:interface>
<cc:implementation>
    <c:if test="#{not empty cc.attrs.node.children}">
        <ul>
            <c:forEach items="#{cc.attrs.node.children}" var="node">
                <li>
                    #{node.data}
                    <my:tree node="#{node}" />
                </li>
            </c:forEach>
        </ul>
    </c:if>
</cc:implementation>
以及组件

<cc:interface componentType="treeComposite">
    <cc:attribute name="node" type="com.example.SomeTreeModel" />
</cc:interface>
<cc:implementation>
    <c:if test="#{not empty cc.node.children}">
        <ul>
            <c:forEach items="#{cc.node.children}" var="node" varStatus="loop">
                <li>
                    #{node.data}
                    <my:tree node="#{cc.parent.node.children[loop.index]}" />
                </li>
            </c:forEach>
        </ul>
    </c:if>
</cc:implementation>

  • #{node.data}

谢谢你的帮助,但也谢谢你的帮助,但是@Kukeltje根据你提供的链接中的共识,我已经编辑了我的答案,包括了博客文章中最重要的部分。因此,我希望我已经反驳了链接丢失的问题:)@Kukeltje根据您提供的链接中的共识,我已经编辑了我的答案,以包括博客文章中最重要的部分。因此,希望我已经反驳了链接丢失的问题:)
<cc:interface>
    <cc:attribute name="node" type="com.example.SomeTreeModel" />
</cc:interface>
<cc:implementation>
    <c:if test="#{not empty cc.attrs.node.children}">
        <ul>
            <c:forEach items="#{cc.attrs.node.children}" var="node">
                <li>
                    #{node.data}
                    <my:tree node="#{node}" />
                </li>
            </c:forEach>
        </ul>
    </c:if>
</cc:implementation>
@FacesComponent("treeComposite")
public class TreeComposite extends UINamingContainer {

    private SomeTreeModel node;

    @Override
    public void setValueExpression(String name, ValueExpression expression) {
        if ("node".equals(name)) {
            setNode((SomeTreeModel) expression.getValue(getFacesContext().getELContext()));
        }
        else {
            super.setValueExpression(name, expression);
        }
    }

    public SomeTreeModel getNode() {
        return node;
    }

    public void setNode(SomeTreeModel node) {
        this.node = node;
    }

}
<cc:interface componentType="treeComposite">
    <cc:attribute name="node" type="com.example.SomeTreeModel" />
</cc:interface>
<cc:implementation>
    <c:if test="#{not empty cc.node.children}">
        <ul>
            <c:forEach items="#{cc.node.children}" var="node" varStatus="loop">
                <li>
                    #{node.data}
                    <my:tree node="#{cc.parent.node.children[loop.index]}" />
                </li>
            </c:forEach>
        </ul>
    </c:if>
</cc:implementation>