OmniFaces loading/unloading ViewScopedBean
OmniFaces loading/unloading ViewScopedBean
为了缩小我们的问题范围,我们正在从 Jboss 6 EAP (JSF 2.1) 升级到 Jboss 7 EAP (JSF 2.2)。我们的工作应用程序现在有 OmniFaces ViewScoped beans 的问题。
版本:
- Mojarra 2.2.14
- OminFaces 2.6.9
- PrimeFaces 6.2.5
我们有这样的数据table:
<p:dataTable id="tblLegalHolds" widgetVar="tableLegalHolds" var="row"
rowKey="#{row.id}" filterEvent="enter"
lazy="true"
value="#{bean.lazyDataModel}"
rows="15">
注意: 我们的 bean 是 OmniFaces ViewScoped 并且我们的 table 在这一点上工作正常!
问题:
接下来我们添加一个包含导航到新页面的列,如下所示:
<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 以证明它被调用了两次。我们的面孔-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>
所以我的问题是:
- 为什么删除 "include-view-params" 会起作用?
- 这是一个类似于最近的 ViewScoped 问题的错误吗? : https://github.com/omnifaces/omnifaces/issues/463
这似乎是 Mojarra 中的一个错误。它在确定另一个视图的视图参数时间接调用 PreDestroyViewMapEvent
。
在渲染响应阶段,当要生成UIOutcomeTarget
组件(例如<p:button>
)的URL时,includeViewParams
设置为true
(如您的导航案例中所定义),那么它需要查询目标视图的所有 <f:viewParam>
。为了实现这一点,它需要构建一个 UIViewRoot
实例。
然而,它实际上暂时将新 UIViewRoot
设置为 faces 上下文的当前视图根,以便访问 <f:viewParam>
。它会恢复原来的视图,但这是它在 Mojarra 中出错的地方。 It is restoring context.setProcessingEvents(true)
too early。它实际上应该在 恢复原始视图后完成。
目前,最好的办法是针对 Mojarra 报告此问题,并避免将 includeViewParams
与 OmniFaces @ViewScoped
.
结合使用
报告的问题:https://github.com/eclipse-ee4j/mojarra/issues/4503
PR 提供:https://github.com/eclipse-ee4j/mojarra/pull/4730
此修复程序将包含在 Mojarra 的 2.3.15、3.0.1 和 4.0.0 中。
为了缩小我们的问题范围,我们正在从 Jboss 6 EAP (JSF 2.1) 升级到 Jboss 7 EAP (JSF 2.2)。我们的工作应用程序现在有 OmniFaces ViewScoped beans 的问题。
版本:
- Mojarra 2.2.14
- OminFaces 2.6.9
- PrimeFaces 6.2.5
我们有这样的数据table:
<p:dataTable id="tblLegalHolds" widgetVar="tableLegalHolds" var="row"
rowKey="#{row.id}" filterEvent="enter"
lazy="true"
value="#{bean.lazyDataModel}"
rows="15">
注意: 我们的 bean 是 OmniFaces ViewScoped 并且我们的 table 在这一点上工作正常!
问题: 接下来我们添加一个包含导航到新页面的列,如下所示:
<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 以证明它被调用了两次。我们的面孔-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>
所以我的问题是:
- 为什么删除 "include-view-params" 会起作用?
- 这是一个类似于最近的 ViewScoped 问题的错误吗? : https://github.com/omnifaces/omnifaces/issues/463
这似乎是 Mojarra 中的一个错误。它在确定另一个视图的视图参数时间接调用 PreDestroyViewMapEvent
。
在渲染响应阶段,当要生成UIOutcomeTarget
组件(例如<p:button>
)的URL时,includeViewParams
设置为true
(如您的导航案例中所定义),那么它需要查询目标视图的所有 <f:viewParam>
。为了实现这一点,它需要构建一个 UIViewRoot
实例。
然而,它实际上暂时将新 UIViewRoot
设置为 faces 上下文的当前视图根,以便访问 <f:viewParam>
。它会恢复原来的视图,但这是它在 Mojarra 中出错的地方。 It is restoring context.setProcessingEvents(true)
too early。它实际上应该在 恢复原始视图后完成。
目前,最好的办法是针对 Mojarra 报告此问题,并避免将 includeViewParams
与 OmniFaces @ViewScoped
.
报告的问题:https://github.com/eclipse-ee4j/mojarra/issues/4503
PR 提供:https://github.com/eclipse-ee4j/mojarra/pull/4730
此修复程序将包含在 Mojarra 的 2.3.15、3.0.1 和 4.0.0 中。