如何在Ajax调用或重载后将对象保持在JSF Flash作用域上
How to keep objects on JSF Flash Scope after Ajax call or Reload?
我有一个'大'项目,大表和很多关系…因此,在我的表单中,我有几个选项卡,一些对话框和许多PrimeFaces命令按钮来管理所有带有Ajax请求的CRUD。
xhtml结构是这样的:
<ui:define name="content">
<h:body>
<p:growl id="growl"/>
<h:form id="formCars" enctype="multipart/form-data">
<p:tabView id="formTabView" scrollable="true" >
<p:tab title="Tab1">
<ui:include src="tabOne/tabOne.xhtml" />
</p:tab>
<p:tab title="Tab2">...</p:tab>
...
<p:tab title="Tab8">...</p:tab>
</p:tabView>
<br />
<div align="center">
<p:commandButton id="cmdSave" value="Save"
action="#{controllerMB.save}" icon="ui-icon-disk"
update="@form :growl" process="@form @this" validateClient="true" />
</div>
</h:form>
<p:dialog header="Car Color" id="modalCarColor" widgetVar="modalCarColor" appendToBody="true" modal="true" height="500" width="700" dynamic="true" closeOnEscape="true" >
<p:ajax event="close" listener="#{controllerMB.closeModalCarColor}" update="@this,:formCarColor"/>
<h:form id="formCarColor">
<ui:include src="tabTwo/carColor/carColor.xhtml" />
</h:form>
</p:dialog>
<p:dialog header="Car Size" ...>
<p:ajax event="close" .../>
<h:form id="formCarColor">...</h:form>
</p:dialog>
</h:body>
</ui:define>
它完美地工作…问题是当我尝试重新加载页面时…我通过使用
来保持主要对象在闪光灯上FacesContext.getCurrentInstance().getExternalContext().getFlash().keep(key)
在@ViewScoped控制器的@PostConstruct上。如果我访问页面,不触摸ajax按钮,我可以重新加载页面没有问题…但是,如果我触摸任何引起ajax请求的东西,JSF Flash scope就会丢失主对象,因此我无法重新加载页面。
我的控制器是这样构建的:
@ManagedBean(name="controllerMB")
@ViewScoped
public class ControllerMB implements Serializable{
// attributes
// ----------
@PostConstruct
public void init(){
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
}
if(car==null) {
redirect_back();
return;
}
// attributes initialization and form preparation
// -----
}
// methods
// ----------
}
作为主要对象的"car"只是一个例子。
对此有任何解决方案或变通方法吗?
我想在"意外重新加载"后保持状态,但是,它不能与Flash一起工作。
此外,是否有可能捕获/处理从浏览器(也许与js)重新加载事件?我的意思是,这样我就可以在重载之前在主对象中处理表单。
我在我的项目中使用PrimeFaces 5.3, JSF 2, Maven, Tomcat 7和Java 7。
提前感谢大家。
编辑1:在尝试了用户NightEagle提到的解决方案后,它几乎工作了…我修改了代码:
<ui:composition ....>
<f:metadata>
<f:event type="preRenderView" listener="#{controllerMB.preRender}"/>
</f:metadata>
<ui:define name="title">...</ui:define>
<ui:define name="header">...</ui:define>
<ui:define name="content">...</ui:define>
</ui:composition>
和
public void preRender()
{
System.out.print("PRE-RENDER ");
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
System.out.println("KEEP");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
} else {
System.out.println("PUT");
FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car",car);
}
}
奇怪的是,第一个ajax调用是好的,第二个之后…开始弹出JSF1095错误。
一些对话框打开后的输出:
PRE-RENDER PUT
PRE-RENDER KEEP
PRE-RENDER KEEP
Jul 14, 2017 11:43:59 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:00 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
PRE-RENDER PUT
Jul 14, 2017 11:44:04 AM com.sun.faces.context.flash.ELFlash setCookie
WARNING: JSF1095: The response was already committed by the time we tried to set the outgoing cookie for the flash. Any values stored to the flash will not be available on the next request.
提前感谢大家,仍在寻找解决方案
我想我知道如何解决它(它在我的项目中帮助了我)
<f:metadata>
<f:event type="preRenderView" listener="#{myBean.preRender}"/>
</f:metadata>
支持bean: public class MyBean
{
@PostConstruct
public void init(){
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
}
}
public void preRender()
{
if(FacesContext.getCurrentInstance().getExternalContext().getFlash().containsKey("car")) {
FacesContext.getCurrentInstance().getExternalContext().getFlash().keep("car");
}
}
}
"preRenderView事件在每个HTTP请求(是的,这也包括ajax请求!)上被调用。"(c) https://stackoverflow.com/a/9844616/3163475
相关文章:
- 监视函数从服务返回不起作用,但作用域函数起作用
- 将作用域存储在JSON中
- 从控制器继承了隔离的作用域以生成可重用的指令
- 从ng模板访问作用域
- 调用私有作用域
- 对父作用域的指令更新延迟了一步
- 正在$rootScope上达到控制器作用域$在内部控制器上
- 两个指令创建新的继承的和隔离的作用域-元素得到哪个
- 这两个关于 JavaScript 作用域链的例子有什么区别?
- 在具有命名作用域的自定义Polymer元素中隐藏表行
- AngularJS指令隔离作用域
- Angularjs:修改js中的作用域,稍后在页面中使用
- 访问多个指令的隔离作用域
- Javascript作用域和Ajax调用;工作不正常
- 向Angular作用域对象添加对象数组——TypeError
- ng重复中的ng模型-初始化唯一作用域属性
- 在put方法之前从作用域获取数据
- 如何在html中以角度显示自定义指令的作用域
- 如何在Ajax调用或重载后将对象保持在JSF Flash作用域上
- 使用JSF AJAX方法保持JavaScript模块作用域