使JSF 2.0执行方法,因为它们被分配给params,而不是存储对方法的引用?

时间:2012-08-03 20:24:01

标签: java jsf jsf-2

在开始之前,如果这个问题标题的措辞令人困惑,我道歉。我希望我的解释会更清楚。

在我的应用程序的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中设置此新模板将使用的其他一些对象。例如,它设置了importantInfoimportantInfoToo的值,而另一个模板需要这些值。

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,则importantInfoimportantInfoToo将不会设置或具有不可预测的值。这是非常令人失望的,因为我希望initForOtherTemplate在父模板中执行,而不是在这里,这感觉很麻烦。

如何获取参数的赋值以立即实际执行该方法而不是存储对它的引用?

1 个答案:

答案 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>

另见: