在开始之前,如果这个问题标题的措辞令人困惑,我道歉。我希望我的解释会更清楚。
在我的应用程序的JSF模板中,我想要包含另一个模板并向其传递一个包含应用程序方法结果的参数。在这个父模板中,我有:
<ui:repeat var="loopObject" value="#{ApplicationBean.objectList}">
<ui:include src="anotherTemplate.xhtml">
<ui:param name="firstParam"
value="#{ApplicationBean.initForOtherTemplate(loopObject)}" />
</ui:include>
</ui:repeat>
但事实证明,initForOtherTemplate
此时未执行,firstParam
包含对该方法的引用,而不是其返回值,正如我预期的那样。
实际上,虽然initForOtherTemplate
确实有返回值,但anotherTemplate.xhtml
不需要它。但是,该方法会在ApplicationBean
中设置此新模板将使用的其他一些对象。例如,它设置了importantInfo
和importantInfoToo
的值,而另一个模板需要这些值。
anotherTemplate.xhtml
包含:
<ui:remove>
<!--
When a parameter contains a method call, the method isn't executed until
the parameter is referenced. So we reference the parameter here and ignore
the results. There must be a better way.
-->
</ui:remove>
<h:outputText value="#{firstParam}" style="display: none;" />
<h:outputText value="#{ApplicationBean.importantInfo}" />
<h:outputText value="#{ApplicationBean.importantInfoToo}" />
如果此模板未引用firstParam
,则importantInfo
和importantInfoToo
将不会设置或具有不可预测的值。这是非常令人失望的,因为我希望initForOtherTemplate
在父模板中执行,而不是在这里,这感觉很麻烦。
如何获取参数的赋值以立即实际执行该方法而不是存储对它的引用?
答案 0 :(得分:3)
<ui:repeat>
是UIComponent
,在视图渲染时运行。 <ui:include>
是TagHandler
(如JSTL),在视图构建期间运行。因此,在<ui:include>
运行的那一刻,<ui:repeat>
未运行,因此#{loopObject}
在EL范围内根本不可用。
<ui:repeat>
替换<c:forEach>
应解决此特定问题。
<c:forEach var="loopObject" items="#{ApplicationBean.objectList}">
<ui:include src="anotherTemplate.xhtml">
<ui:param name="firstParam"
value="#{ApplicationBean.initForOtherTemplate(loopObject)}" />
</ui:include>
</c:forEach>