我正在使用<f:viewParam>
传递参数,如下所示。
<ui:define name="metaData">
<f:metadata>
<f:viewParam name="id" value="#{bean.entity}" converter="#{converter}"/>
</f:metadata>
</ui:define>
只有在加载/刷新页面时才能处理此<f:viewParam>
吗?
这只是因为<f:viewParam>
指定的转换器成本很高,会将通过查询字符串传递的值转换为JPA实体。因此,它涉及昂贵的数据库事务,即使使用<p:commandButton>
,<p:commandLink>
这样的组件进行 ajaxical 回发时也是如此。
因此,例如,当单击<p:commandLink>
( ajaxical )时,不应执行昂贵的业务服务(在转换器中)。可以这样做吗?
当rendered
属性针对facesContext.postback
rendered="#{not facesContext.postback}"
进行评估,但属性rendered
为not documented时,这会以某种方式运作(尽管仍然很奇怪)。因此,它是不可靠的。
答案 0 :(得分:2)
您可以通过创建扩展<f:viewParam>
的自定义标记来实现此目的,其中您将提交的值存储为实例变量,该变量不存储在JSF视图状态而不是JSF视图状态中{{1} 1}}默认情况下。在请求结束时,所有UI组件实例都将被销毁。它们在请求开始时重新创建。当提交的值为<f:viewParam>
时,它不会调用转换器,也不会调用模型设置器。这一切都在Arjan Tijms' blog详细阐述。
OmniFaces从版本1.0开始提供了<o:viewParam>
的即用型解决方案,另请参阅my own blog。根据您的问题历史记录,您已经在使用OmniFaces,因此您基本上需要做的就是将null
替换为f:
。
o:
在同一视图的回发期间,这不会调用模型设定器(也不会转换为转换器)。
这在某种程度上起作用(尽管不够奇怪),当渲染的属性针对facesContext.postback进行评估时,如render =&#34;#{faces facesContext.postback}&#34;但是没有记录所呈现的属性。因此,它是不可靠的。
那是因为<f:viewParam>
本质上是一个UIInput
组件(否则它无法像往常一样执行转换,验证,模型更新和所有这些事情输入组件)因此只是支持UIComponent
属性的rendered
。然而,这没有明确记录,因为它实际上没有向HTML输出呈现任何内容(这也是为什么它是<ui:define name="metaData">
<f:metadata>
<o:viewParam name="id" value="#{bean.entity}" converter="#{converter}"/>
</f:metadata>
</ui:define>
而不是f:xxx
)。但是使用此属性,您实际上可以控制回发期间的行为,因为此属性在also方法中进行了processDecodes()
评估,该方法在应用请求值阶段期间调用。