是否有可能有一个具有ui:重复的JSF组件并且在重复调用内部使用相同的组件?这是因为我正在构建问题树:
<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?
答案 0 :(得分:4)
使用视图构建时间标记来停止递归而不是视图渲染时间标记。组件树是在视图构建期间构建的。在视图构建期间不评估rendered
属性,而是在视图渲染时间期间评估StackOverflowError
属性。因此,您的构造基本上将自己包含在无限循环中。您应该已经知道<h:panelGroup rendered>
是由递归引起的,因此内存堆栈无法再处理它(通常约为1000次迭代)。
将<c:if test>
替换为renderQuestions
,它将按预期工作。通过省略对孩子的检查,可以简化<ui:repeat>
。如果没有孩子,{{1}}无法呈现任何内容。
如果您碰巧在此构造中使用视图范围bean并且您正在使用Mojarra实现,那么请确保您升级到至少2.1.18,因为将视图构建时标记属性绑定到视图范围的bean属性将在旧版本中打破了视图范围。
答案 1 :(得分:0)
根据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属性。