Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf 如何阻止递归复合组件递归地包含自身_Jsf_Jsf 2_Recursion_Facelets_Composite Component - Fatal编程技术网

Jsf 如何阻止递归复合组件递归地包含自身

Jsf 如何阻止递归复合组件递归地包含自身,jsf,jsf-2,recursion,facelets,composite-component,Jsf,Jsf 2,Recursion,Facelets,Composite Component,有没有可能让一个JSF组件具有ui:repeat,并且在repeat调用中包含相同的组件?这是因为我正在构建问题之树: <cc:interface> <cc:attribute name="questions" required="true" /> <cc:attribute name="renderQuestions" required="true" default="true" /> </cc:interface> <c

有没有可能让一个JSF组件具有ui:repeat,并且在repeat调用中包含相同的组件?这是因为我正在构建问题之树:

<cc:interface>
    <cc:attribute name="questions" required="true" />
    <cc:attribute name="renderQuestions" required="true" default="true" />
</cc:interface>

<cc:implementation>

    <c:if test="#{cc.attrs.renderQuestions}">
        <ui:repeat value="#{cc.attrs.questions}" var="q">
            <p:panelGrid columns="2">
                <h:outputLabel value="#{q.question}"></h:outputLabel>
                <p:selectBooleanButton onLabel="#{messages['commons.yes']}"
                    offLabel="#{messages['commons.no']}" onIcon="ui-icon-check"
                    offIcon="ui-icon-close" value="#{q.ok}">
                    <p:ajax update="@all"></p:ajax>
                </p:selectBooleanButton>
            </p:panelGrid>

            <cf:question renderQuestions="#{q.ok}" questions="#{q.children}" />

        </ui:repeat>
    </c:if>

</cc:implementation>


当前我有stackoverflow?

使用视图生成时间标记来停止递归,而不是使用视图渲染时间标记。组件树是在视图生成期间生成的。
rendered
属性不会在视图生成时计算,而是在视图渲染时计算。所以你的构造基本上是把自己包含在一个无限循环中。您应该已经知道,
stackoverflowerrror
是由递归引起的,递归太深,内存堆栈无法再处理它(通常约1000次迭代)

替换
,它将按预期工作。顺便说一句,
renderQuestions
可以通过省略对子项的检查来简化。如果没有子对象,
无论如何都不会呈现任何内容

如果您碰巧在此构造中使用了视图范围bean,并且正在使用Mojarra实现,那么请确保至少升级到2.1.18,因为在旧版本中,将视图构建时间标记属性绑定到视图范围bean属性会破坏视图范围

另见:
  • -解释“视图构建时间”与“视图渲染时间”

使用视图生成时间标记来停止递归,而不是使用视图渲染时间标记。组件树是在视图生成期间生成的。
rendered
属性不会在视图生成时计算,而是在视图渲染时计算。所以你的构造基本上是把自己包含在一个无限循环中。您应该已经知道,
stackoverflowerrror
是由递归引起的,递归太深,内存堆栈无法再处理它(通常约1000次迭代)

替换
,它将按预期工作。顺便说一句,
renderQuestions
可以通过省略对子项的检查来简化。如果没有子对象,
无论如何都不会呈现任何内容

如果您碰巧在此构造中使用了视图范围bean,并且正在使用Mojarra实现,那么请确保至少升级到2.1.18,因为在旧版本中,将视图构建时间标记属性绑定到视图范围bean属性会破坏视图范围

另见:
  • -解释“视图构建时间”与“视图渲染时间”

根据巴卢斯的回答,我创建了这样一个解决方案

<composite:interface>
    [..]
    <composite:attribute name="level" required="true" default="0"/>
</composite:interface>
<composite:implementation>

        <c:if test="#{cc.attrs.level == 0}">
            <a4j:repeat value="#{cc.attrs.list}" var="subList" rendered="#{cc.attrs.list != null}">

                    <xx:recursiveComponent list="#{subList}" id="subComponent" level="1"/>

            </a4j:repeat>   
        </c:if>

</composite:implementation>

[..]

在构建时使用level属性以避免无休止的递归,a4j:repeat(在您的情况下是ui:repeat)的renered属性将在渲染时进行评估。

基于BalusC的答案,我创建了一个类似这样的解决方案

<composite:interface>
    [..]
    <composite:attribute name="level" required="true" default="0"/>
</composite:interface>
<composite:implementation>

        <c:if test="#{cc.attrs.level == 0}">
            <a4j:repeat value="#{cc.attrs.list}" var="subList" rendered="#{cc.attrs.list != null}">

                    <xx:recursiveComponent list="#{subList}" id="subComponent" level="1"/>

            </a4j:repeat>   
        </c:if>

</composite:implementation>

[..]

level属性在构建时使用,以避免无休止的递归,a4j:repeat(或者在您的情况下是ui:repeat)的renered属性将在渲染时求值。

理论上,嵌套两个
ui:repeat
标记没有问题。不过,这取决于您的
cf:question
标记的内容。您好,cf:question的内容与上面的代码相同,它是呈现该视图的递归调用。我们的目标是编写问题及其子问题(如果有),然后,感谢您在视图端执行这种递归。为什么不在问题上构建一个双重迭代呢?不幸的是,我想要的是一个n层次的问题,这就是为什么双重迭代不起作用的原因。理论上,嵌套两个
ui:repeat
标记没有问题。不过,这取决于您的
cf:question
标记的内容。您好,cf:question的内容与上面的代码相同,它是呈现该视图的递归调用。我们的目标是编写问题及其子问题(如果有),然后,感谢您在视图端执行这种递归。为什么你不在问题上建立一个双重迭代呢?不幸的是,我想要的是一个n层次的问题,这就是为什么双重迭代不行的原因。嗨,巴卢斯,谢谢你的回答,但是在你上面指定的更改之后,我仍然有相同的错误。我正在更新上面的帖子。显然这个表达式从来没有计算过
false
。看起来renderQuestions=“#{q.ok}”不起作用,但是打印q.ok会显示'false',所以它不应该渲染视图,但它似乎会导致堆栈溢出,很奇怪。嗨,Balus,谢谢你的回复,但是在你上面指定的更改之后,我仍然有相同的错误。我正在更新上面的帖子。很明显,这个表达式从来没有计算过
false
。看起来renderQuestions=“#{q.ok}”不起作用,但是打印q.ok会显示“false”,所以它不应该渲染视图,但它似乎会导致堆栈溢出,这很奇怪。