我使用<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>
等组件进行ajax 回发时也是如此,这是不必要的。
<p:commandLink>
(ajax )时,不应该执行昂贵的业务服务(在转换器中)。这能做到吗?当rendered
属性像rendered="#{not facesContext.postback}"
一样对facesContext.postback
进行评估,但属性rendered
没有记录时,这在某种程度上是有效的(尽管很奇怪)。因此,它是不可靠的。
您可以通过创建扩展<f:viewParam>
的自定义标记来实现这一点,其中您将提交的值存储为实例变量,该实例变量不存储在JSF视图状态中,而是存储在JSF视图状态中,因为默认情况下<f:viewParam>
是这样做的。在请求结束时,所有UI组件实例都被销毁。它们在请求开始时重新创建。当提交值为null
时,它既不会调用转换器也不会调用模型设置器。这一切都在Arjan Tijms的博客中详细阐述。
OmniFaces从1.0版开始就提供了一种<o:viewParam>
风格的现成解决方案,请参阅我自己的博客。根据您的问题历史记录,您已经使用了OmniFaces,因此您基本上需要做的就是将f:
替换为o:
。
<ui:define name="metaData">
<f:metadata>
<o:viewParam name="id" value="#{bean.entity}" converter="#{converter}"/>
</f:metadata>
</ui:define>
这不会在同一视图的回发期间调用模型设置器(也不会调用转换器)。
当渲染属性对facesContext求值时,这在某种程度上是有效的(尽管很奇怪)。postback like rendered="#{不是facesContext。Postback}",但呈现的属性没有记录。因此,它是不可靠的。
这是因为<f:viewParam>
本质上是一个UIInput
组件(否则它将无法执行转换,验证,模型更新和所有的东西,像通常的输入组件),因此只是一个UIComponent
支持rendered
属性。然而,这并没有明确地记录,因为它实际上没有呈现任何HTML输出(这也是为什么它是f:xxx
,而不是h:xxx
)。但是有了这个属性,你实际上可以控制回发过程中的行为,因为这个属性也在应用请求值阶段调用的processDecodes()
方法中求值。