Before I begin, my apologies if the wording of this question's title is confusing. I hope my explanation here will make it much clearer.
In a JSF template of my application, I want to include another template and pass a parameter to it that holds the results of an application method. In this parent template, I have:
<ui:repeat var="loopObject" value="#{ApplicationBean.objectList}">
<ui:include src="anotherTemplate.xhtml">
<ui:param name="firstParam"
value="#{ApplicationBean.initForOtherTemplate(loopObject)}" />
</ui:include>
</ui:repeat>
It turns out, though, that initForOtherTemplate
is not executed at this point and firstParam
contains a reference to that method, rather than its return value, as I expected.
Actually, while initForOtherTemplate
does have a return value, anotherTemplate.xhtml
doesn't need it. However,the method does set up some other objects in ApplicationBean
that this new template will use. For example, it sets values for importantInfo
and importantInfoToo
, which the other template needs.
anotherTemplate.xhtml
contains:
<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}" />
If this template didn't reference firstParam
, then importantInfo
and importantInfoToo
wouldn't be set or have unpredictable values. This is very disappointing, because I expected initForOtherTemplate
to be executed in the parent template, rather than here, which feels messy.
How can I get the assignment of the parameter to actually execute the method immediately rather than store a reference to it?