Primefaces Dialog Framework - 打开对话框 - 关闭它 - 打开另一个对话框

Primefaces Dialog Framework - Open dialog - close it - open another dialog

Primefaces 5.0、JSF 2.2、Wildfly 8.1

以下用例:

  1. 单击视图中的命令按钮(带有一些参数)
  2. bean 方法在数据库中查找某些内容 - 如有必要,将显示 dialog1。在 dialog1 中有一个表单和一个命令按钮。
  3. 单击 dialog1 中的命令按钮,bean 方法在数据库中查找内容。
  4. Dialog1 关闭并显示 dialog2,具体取决于 bean 方法的结果。

bean1.java:

public void buttonClicked() {

    Map<String, Object> options = new HashMap<>();
    options.put("modal", true);
    options.put("widgetVar", "dialog1");
    options.put("id", "dlg1");

if(somethingTrue()) {
RequestContext.getCurrentInstance().openDialog("dialog1.xhtml", options, null);
    }
}

一切都很好。 Dialog1 出现。

dialog1.xhtml:

<h:body>
    <h:form>
        <p:commandButton value="Button" actionListener="#{bean2.dialog1ButtonClicked}" />
    </h:form>
</h:body>

bean2.java:

public void dialog1ButtonClicked() {        
    Map<String, Object> options = new HashMap<>();
    options.put("modal", true);
    options.put("widgetVar", "dialog2");
    options.put("id", "dlg2");    

if(somethingTrue()) {
    RequestContext.getCurrentInstance().openDialog("dialog2.xhtml", options, null);
    }
}

dialog2.xhtml:

<h:body>        
    The operation was successful.
</h:body>

Dialog2 出现在 dialog1 中!

如何关闭 dialog1 并在 dialog1 中不显示 dialog2?

我尝试在打开 dialog2 之前使用 Primefaces 对话框框架关闭 dialog1:

RequestContext.getCurrentInstance().closeDialog(null);
RequestContext.getCurrentInstance().openDialog("dialog2.xhtml", options, null);

Dialog2 没有出现。

我尝试在 AJAX 回调 <p:ajax event="dialogReturn" listener="#{bean1.dialogClosed}"/> 之后打开 dialog2 Dialog2 不显示。

我尝试了客户端 Java 脚本调用:onclick="PF('dialog1').hide()"

Dialog2 仍然嵌套在 dialog1 中。

解决方案:

  • 只打开一个对话框: RequestContext.getCurrentInstance().openDialog("dialog1.xhtml", options, null);
    • 对话流由主面板的 ajax 更新控制,其中呈现的属性绑定到 bean 属性,因此完全由 bean 控制。

dialog1.xhtml:

<p:dialog class="userRegisterDialog" header="#{bean.dailogHeader}" 
                          modal="true" resizable="false" draggable="false">

    <p:ajax event="close" listener="#{bean2.closeRegistration}" update=":update"/>

    <p:panel id="update">
        <p:panel id="step1" rendered="#{bean.showStep1}">
            <h:form>
                <p:commandButton class="continueButton" value="Button1" actionListener="#{bean.doStep1}" update=":update"/>
            </h:form>
        </p:panel>
        <p:panel id="step2" rendered="#{bean.showStep2}">                        
            <h:form>
                <p:commandButton class="closeButton" value="Button2" actionListener="#{bean.doStep2}" update=":update"/>
            </h:form>               
        </p:panel>
    </p:panel>
</p:dialog>

对话框 bean:

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

@ManagedBean
@ViewScoped
public class Bean implements Serializable 
    {

    private boolean showStep1 = true;
    private boolean showStep2 = false;

    public void doStep1(ActionEvent actionEvent) {

        if(doSomething())
        {
            setShowStep1(false);            
            setShowStep2(true);
        }
    }            

    public void doStep2(ActionEvent actionEvent) {

        if(doSomething2())
        {
            RequestContext.getCurrentInstance().closeDialog(null);
        }
    }

    // Getter and setter ...    
}

对话框关闭的另一个 bean:

@ManagedBean
@RequestScoped
public class Bean2 implements Serializable {
    public void closeRegistration() { 
         FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("bean");
    }    
}

方法 closeRegistration 删除了 viewscoped bean。因此,在同一页面内再次调用对话框将从头开始对话框流程。

使用 onHide 你可以像这样打开另一个对话框。

<p:dialog class="userRegisterDialog" header="#{bean.dailogHeader}" modal="true" resizable="false" draggable="false" onHide="PF('dialog2').show();>
</p:dialog>

它在使用转义键关闭对话框时也有效。

我们也可以在 onsuccessonerroroncomplete 中关闭对话框。查看图片以供参考