【问题标题】:OmniFaces loading/unloading ViewScopedBeanOmniFaces 加载/卸载 ViewScopedBean
【发布时间】:2018-12-25 05:59:45
【问题描述】:

为了缩小我们的问题范围,我们正在从 Jboss 6 EAP (JSF 2.1) 升级到 Jboss 7 EAP (JSF 2.2)。我们的工作应用程序现在遇到了 OmniFaces ViewScoped bean 的问题。

版本:

  • Mojarra 2.2.14
  • OminFaces 2.6.9
  • PrimeFaces 6.2.5

我们有一个这样的数据表:

<p:dataTable id="tblLegalHolds" widgetVar="tableLegalHolds" var="row"
        rowKey="#{row.id}" filterEvent="enter" 
        lazy="true"
        value="#{bean.lazyDataModel}"
        rows="15">

注意:我们的 bean 是 OmniFaces ViewScoped,此时我们的表工作正常!

问题: 接下来我们添加一个包含导航到新页面的列,如下所示:

<p:column width="60" exportable="false">
    <p:button value="Open" outcome="legal-hold-edit">
        <f:param name="id" value="#{row.id}" />
    </p:button>
</p:column>

现在我们的 bean 正在立即加载和卸载,如果我们查看 HTML 的源代码,我们会看到 Omnifaces 脚本像这样添加了两次......

OmniFaces.Unload.init('f1c1ff81-c87f-4406-b98f-a3eaff977e96');
OmniFaces.Unload.init('45e7de9d-53c7-4426-a972-797c48c46733');

我们将@PostConstruct 添加到我们的 ViewScoped bean 以证明它被调用了两次。对于导航,我们的 faces-config.xml 看起来像这样。

<navigation-case>
    <from-outcome>legal-hold-edit</from-outcome>
    <to-view-id>/legal/legal-hold-edit.xhtml</to-view-id>
    <redirect include-view-params="true"/>
</navigation-case>

现在有趣的是,如果我们像下面的代码一样删除 faces-config.xml 中的“include-view-params”,一切都开始正常工作,ViewScoped bean 只创建一次,并且只有 1 个 OmniFaces.Unload.init 脚本添加到页面。

<navigation-case>
    <from-outcome>legal-hold-edit</from-outcome>
    <to-view-id>/legal/legal-hold-edit.xhtml</to-view-id>
    <redirect/>
</navigation-case>

作为补充说明,我们的结果页面使用 o:viewparam 来接收这样的参数:

    <f:metadata>
        <o:viewParam name="id" value="#{legalHoldForm.legalHold}" required="false" />
        <f:event type="preInvokeAction" listener="#{controller.initializeViewLegalHold}" />
   </f:metadata>

所以我的问题是:

  1. 为什么删除“include-view-params”会使其工作?
  2. 这是一个类似于最近的 ViewScoped 问题的错误吗? :https://github.com/omnifaces/omnifaces/issues/463

【问题讨论】:

    标签: primefaces jsf-2.2 omnifaces


    【解决方案1】:

    这似乎是 Mojarra 中的一个错误。在计算另一个视图的视图参数时,它间接调用了PreDestroyViewMapEvent。

    在渲染响应阶段,当要生成UIOutcomeTarget 组件的URL(例如&lt;p:button&gt;),并且includeViewParams 设置为true(在您的导航案例中定义),然后它需要咨询目标视图的所有&lt;f:viewParam&gt;。为了实现这一点,它需要构建它的UIViewRoot 实例。

    然而,为了访问&lt;f:viewParam&gt;,它实际上临时将新的UIViewRoot 设置为人脸上下文的当前视图根。它将恢复原始视图,但这是 Mojarra 出错的地方。 It is restoring context.setProcessingEvents(true) too early。它实际上应该在 恢复原始视图之后完成。

    目前,最好的办法是针对 Mojarra 报告此问题,并避免将 includeViewParams 与 OmniFaces @ViewScoped 结合使用。

    【讨论】:

      【解决方案2】:

      问题报告:https://github.com/eclipse-ee4j/mojarra/issues/4503

      公关提供:https://github.com/eclipse-ee4j/mojarra/pull/4730

      此修复将包含在 Mojarra 的 2.3.15、3.0.1 和 4.0.0 中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多