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

如何获得参数的分配以立即实际执行该方法,而不是存储对它的引用?

4

1 回答 1

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>

也可以看看:

于 2012-08-03T20:33:58.180 回答