与here
基本相同的问题如何在我重定向到其他浏览器标签的页面上保留ViewScoped bean:
firstPage.xhtml:
<h:commandLink action="#{controller.redirect}" value="#{bean.value} target="_blank"/>
当重定向/导航完成初始化其他bean时,它会在进程中销毁这个#{bean}。在重定向的代码中,我甚至没有使用#{bean}。这曾经与
一起使用<a4j:keepAlive>
这是我目前的设置。 bean类:
@ViewScoped
public class Bean{
@PreDestroy
public void onDestroy(){ // being destroyed when I don't want to }
}
面-配置:
<navigation-rule>
<from-view-id>/firstPage.xhtml</from-view-id>
<navigation-case>
<from-outcome>redirect</from-outcome>
<to-view-id>/secondPage.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
答案 0 :(得分:2)
您需要像Luiggi建议的那样暂时将数据存储在会话中,或者通过查询参数将数据(或足以重新获取数据的密钥)传递到目标视图。即使您没有重定向和/或定位新窗口/标签,也是如此。
查看范围很奇怪。只有当用户停留在同一视图上时,它才存在。当JSF看到视图已被导航离开时,它将自动销毁任何作用于该视图的bean。
您可以通过两种方式导航到其他视图。第一个是非面孔请求,例如来自h:link
或h:button
。在这种情况下,之前的视图没有被恢复,因此JSF不会知道有任何视图范围的bean要销毁。第二个是面部请求,例如来自h:commandLink
或h:commandButton
,返回void
或null
以外的内容。在这种情况下,会有一个回发到视图,该视图将被恢复以处理操作。如果该操作的结果是远离该视图,重定向或不重定向,那么任何作用于该视图的bean都将被销毁。
在幕后,视图范围本质上是会话范围,具有一些用于清理“旧”数据的内置语义。如果用户不在多个窗口/选项卡中打开应用程序并且仅使用应用程序内提供的导航(即,不是浏览器后退/前进按钮),这实际上很有效。但是,由于我们讨论的是针对Web浏览器,因此在我看来,视图范围非常无用(唯一的例外是您可以控制目标浏览器并完全禁用后退/前进/重新加载/位置的情况,但它不会听起来就像你在那种环境中一样。)