如何阻止递归复合组件递归包含自身 [英] How to stop recursive composite component from including itself recursively

查看:132
本文介绍了如何阻止递归复合组件递归包含自身的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可能有一个具有ui:repeat的JSF组件,并且在repeat调用内部有相同的组件?这是因为我正在构建问题树:

Is it possible to have a JSF component that has ui:repeat and inside the repeat call the same component? It's because I'm building tree of question:

<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吗?

Currently I'm having stackoverflow?

推荐答案

使用视图构建时间标签而不是视图呈现时间标签来停止递归.组件树是在视图构建期间构建的. rendered属性不是在视图构建期间评估的,而是在视图渲染期间评估的.因此,您的构造基本上将自己包含在无限循环中.您应该已经知道StackOverflowError是由如此深的递归导致的,以至于内存堆栈无法再处理它了(通常约1000次迭代).

Use a view build time tag to stop the recursion instead of a view render time tag. The component tree is built during view build time. The rendered attribute isn't evaluated during view build time, but instead during view render time. So your construct basically keeps including itself in an infinite loop. You should already know that StackOverflowError is caused by a recursion so deep that the memory stack can't handle it anymore (usually around ~1000 iterations).

<c:if test>替换<h:panelGroup rendered>,它将按预期工作.顺便说一句,可以通过省略对子级的检查来简化renderQuestions.如果没有子代,<ui:repeat>不会渲染任何内容.

Replace <h:panelGroup rendered> by a <c:if test> and it'll work as expected. The renderQuestions can by the way be simplified by omitting the check on children. The <ui:repeat> won't render anything anyway if there are no children.

如果您恰好在此构造中使用视图作用域的bean,并且正在使用Mojarra实现,则请确保至少升级到2.1.18,因为将视图构建时间标签属性绑定到视图作用域的bean属性会在旧版本中,会破坏视图范围.

If you happen to use view scoped beans in this construct and you're using Mojarra implementation, then make sure that you upgrade to at least 2.1.18, because binding a view build time tag attribute to a view scoped bean property would in older versions break the view scope.

  • JSTL in JSF2 Facelets... makes sense? - explains "view build time" versus "view render time"

这篇关于如何阻止递归复合组件递归包含自身的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆