I'm using an <f:viewParam>
to pass a parameter as follows.
<ui:define name="metaData">
<f:metadata>
<f:viewParam name="id" value="#{bean.entity}" converter="#{converter}"/>
</f:metadata>
</ui:define>
Is it possible to process this <f:viewParam>
, only when the page is loaded/refreshed?
It is just because the converter as specified with the <f:viewParam>
is costly that converts the value passed through the query-string to a JPA entity. Hence, it involves an expensive database transaction, even when doing ajaxical postbacks using components like <p:commandButton>
, <p:commandLink>
which is unnecessary.
So, when for example, a <p:commandLink>
(ajaxical) is clicked, the expensive business service (in the converter) should not be executed. Can this be done?
This somehow works (strange enough nevertheless), when the rendered
attribute is evaluated against facesContext.postback
like rendered="#{not facesContext.postback}"
but the attribute rendered
is not documented. Hence, it is unreliable.
You can achieve this by creating a custom tag extending <f:viewParam>
wherein you store the submitted value as an instance variable which isn't stored in JSF view state instead of in the JSF view state as the <f:viewParam>
by default does. By end of request, all UI component instances are destroyed. They are recreated in beginning of the request. When submitted value is null
, then it won't call the converter nor the model setter. This all is elaborated in Arjan Tijms' blog.
OmniFaces offers already since version 1.0 a ready to use solution in flavor of <o:viewParam>
, see also my own blog on that. Based on your question history, you're already using OmniFaces, so all you basically need to do is to replace f:
by o:
.
<ui:define name="metaData">
<f:metadata>
<o:viewParam name="id" value="#{bean.entity}" converter="#{converter}"/>
</f:metadata>
</ui:define>
This won't call the model setter (nor the converter) during postbacks on the same view.
This somehow works (strange enough nevertheless), when the rendered attribute is evaluated against facesContext.postback like rendered="#{not facesContext.postback}" but the attribute rendered is not documented. Hence, it is unreliable.
That's because the <f:viewParam>
is in essence an UIInput
component (else it wouldn't be able to perform conversion, validation, model-update and all that stuff like usual input components) which is thus just an UIComponent
supporting a rendered
attribute. This is however not explicitly documented as it actually doesn't render anything to the HTML output (that's also why it's a f:xxx
, not a h:xxx
). But with this attribute you can actually control the behavior during postback as this attribute is also evaluated in processDecodes()
method which is invoked during apply request values phase.