我有一个在我的XHTML
中定义的弹出窗口,它根据用户在默认情况下在主屏幕中做出的选择有条件地显示:
<p:dialog id="commentDialogID" header="Enter comment" widgetVar="commentDialog" modal="true" resizable="true" height="auto">
<h:form id="commentForm">
<h:outputLabel for="comment" value="Comment:"/>
<p:inputTextarea id="comment" title="Comment"
rows="6" cols="33"
value="#{managedBean.activeItem.comment}"
required="true">
<f:ajax render="comment"/>
</p:inputTextarea>
<h:commandButton id="commentSubmit" value="Submit" action="#{managedBean.proceed}" onclick="PF('commentDialog').hide();">
<f:ajax render="commentSubmit"/>
</h:commandButton>
</h:form>
</p:dialog>
问题是,一旦这个对话框/弹出窗口被关闭,容器(JBoss
)或框架(JSF/Primefaces
),不确定哪一个,认为整个视图已经关闭,因此在触发这个弹出窗口出现的下一个请求,它重新调用支持bean的@PostConstruct
方法。支持bean是@ViewScoped
。我真的不希望它这样做,相反,我希望它将对话框/弹出框视为页面中的div,其闭包不影响视图状态。
第一次弹出对话框时,@PostConstruct没有被调用,因为呈现页面的初始视图称为@PostConstruct,仍然是活动的。然而,在第二次出现时,它被重新调用,这使我相信这是因为它在第一次之后被关闭,这要么是框架的容器,要么是两者都错误地认为需要重新加载bean。
我能做些什么来防止后台bean在这个对话框关闭后进入@PostConstruct ?
我知道问题出在哪里了。
您正在使用h:commandButton
来提交表单并关闭对话框。
让我们看看你的代码:
<h:commandButton id="commentSubmit" value="Submit" action="#{managedBean.proceed}" onclick="PF('commentDialog').hide();">
<f:ajax render="commentSubmit"/>
</h:commandButton>
在上面的代码中,只要你点击提交按钮:
1. 您的action
将被触发调用ManagedBean方法managedBean.proceed
。
2. 因为你已经绑定了onclick
JS事件,你的对话框被关闭。
在你的action="#{managedBean.proceed}
回来后,它必须更新id commentSubmit
按钮,因为你已经使用了render="commentSubmit"
。
但是当你的action="#{managedBean.proceed}
回到render="commentSubmit"
的时候,你的按钮commentSubmit
被关闭了。因此,这可能是重新初始化ManagedBean的原因。
为了避免这种情况,你可以使用具有oncomplete
属性的Primefaces p:commandButton
,这在这种情况下很有帮助。
<p:commandButton id="commentSubmit" value="Submit" action="#{managedBean.proceed}" update="commentSubmit" oncomplete="PF('commentDialog').hide();" />
所以在上面的例子中,p:dialog
将在action
完成后关闭。