【问题标题】:Process f:viewParam only on page load仅在页面加载时处理 f:viewParam
【发布时间】:2014-05-28 05:22:15
【问题描述】:

我正在使用<f:viewParam> 传递参数,如下所示。

<ui:define name="metaData">
    <f:metadata>
        <f:viewParam name="id" value="#{bean.entity}" converter="#{converter}"/>
    </f:metadata>
</ui:define>

是否可以仅在页面加载/刷新时处理此&lt;f:viewParam&gt;

只是因为&lt;f:viewParam&gt; 指定的转换器成本很高,所以将通过查询字符串传递的值转换为 JPA 实体。因此,它涉及昂贵的数据库事务,即使使用诸如&lt;p:commandButton&gt;&lt;p:commandLink&gt; 之类的组件进行 ajaxical 回发也是不必要的。

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


rendered 属性与facesContext.postbackrendered="#{not facesContext.postback}" 一样被评估但属性renderednot documented 时,这以某种方式起作用(尽管如此奇怪)。因此,它是不可靠的。

【问题讨论】:

标签: jsf jsf-2.2 viewparams


【解决方案1】:

您可以通过创建扩展 &lt;f:viewParam&gt; 的自定义标记来实现这一点,其中您将提交的值存储为实例变量,该变量不存储在 JSF 视图状态中,而不是像 &lt;f:viewParam&gt; 默认情况下那样存储在 JSF 视图状态中.在请求结束时,所有 UI 组件实例都被销毁。它们在请求开始时重新创建。当提交值为null 时,它不会调用转换器,也不会调用模型设置器。这一切都在Arjan Tijms' blog中详细说明。

OmniFaces 从 1.0 版开始就提供了一个类似于&lt;o:viewParam&gt; 的即用型解决方案,另请参见my own blog。根据您的问题历史,您已经在使用 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}" 但呈现的属性没有记录。因此,它是不可靠的。

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 2015-09-01
相关资源
最近更新 更多