如何阻止递归复合组件递归包含自身 [英] How to stop recursive composite component from including itself recursively
问题描述
是否可能有一个具有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.
- JSF2 Facelets中的JSTL ...有意义吗?-解释查看构建时间"与查看渲染时间"
- JSTL in JSF2 Facelets... makes sense? - explains "view build time" versus "view render time"
这篇关于如何阻止递归复合组件递归包含自身的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!