3

我正在使用 an<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 实体的成本很高。因此,它涉及昂贵的数据库事务,即使在使用诸如 之类的组件进行ajaxical<p:commandButton>回发时也是如此,<p:commandLink>这是不必要的。

因此,例如,当单击<p:commandLink>ajaxical)时,不应执行昂贵的业务服务(在转换器中)。这可以做到吗?


rendered当属性被评估为facesContext.postbacklikerendered="#{not facesContext.postback}"但属性rendered记录时,这以某种方式起作用(尽管如此奇怪)。因此,它是不可靠的。

4

1 回答 1

3

您可以通过创建自定义标签扩展来实现这一点,在<f:viewParam>其中您将提交的值存储为实例变量,该实例变量不存储在 JSF 视图状态中,而不是<f:viewParam>默认情况下存储在 JSF 视图状态中。在请求结束时,所有 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 评估呈现的属性时,如 render="#{not facesContext.postback}" 但呈现的属性没有记录。因此,它是不可靠的。

这是因为<f:viewParam>它本质上是一个UIInput组件(否则它将无法执行转换、验证、模型更新和所有像通常的输入组件一样的东西),因此它只是一个UIComponent支持rendered属性。然而,这并没有明确记录,因为它实际上没有向 HTML 输出呈现任何内容(这也是它是 af:xxx而不是 a 的原因h:xxx)。但是使用此属性,您实际上可以控制回发期间的行为,因为此属性也在processDecodes()应用请求值阶段调用的方法中进行评估。

于 2014-05-28T08:39:24.890 回答