【问题标题】:Primefaces Dialog Framework - Open dialog - close it - open another dialogPrimefaces 对话框框架 - 打开对话框 - 关闭它 - 打开另一个对话框
【发布时间】:2015-12-30 02:05:33
【问题描述】:

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 中!

如何关闭对话框 1 并在对话框 1 中显示对话框 2?

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

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

Dialog2 不显示。

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

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

Dialog2 仍然嵌套在 dialog1 中。

【问题讨论】:

  • 为什么要打开带有第一个参数“dialog2.xhtml”的对话框,而不仅仅是展示中的“dialog2”?
  • 您可以尝试使用RequestContext.getCurrentInstance().execute("PF('dialogWidVar').show()") 或RequestContext.getCurrentInstance().execute("PF('dialogWidVar').close()") 关闭/显示服务器端的对话框
  • @JaqenH'ghar:两种方式的结果相同。我只是使用文件名来避免误解。

标签: jsf jsf-2 primefaces dialog


【解决方案1】:

解决方案:

  • 只打开一个对话框: 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。因此,在同一页面内再次调用对话框将从头开始。

【讨论】:

    【解决方案2】:

    使用onHide,您可以打开另一个这样的对话框。

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

    使用转义键关闭对话框时也可以使用。

    【讨论】:

    • 但是有了这个解决方案,你就没有决策路径了!
    • 你的意思是you've got no decision path! ? @克里斯
    • 问题是,根据服务器端方法的结果显示不同的对话框。
    • 所以你的服务器端这样写RequestContext.getCurrentInstance().execute("PF('dialog1').hide();PF('dialog2').show()");
    • 你试过了吗?因为我想我试过这个,但它没有用。对话框仍然是嵌套的。
    【解决方案3】:

    我们也可以关闭onsuccess 或onerror 或oncomplete 中的对话框。检查图片以供参考

    【讨论】:

    • 请将代码和数据添加为文本 (using code formatting),而不是图像。图片:A)不允许我们复制粘贴代码/错误/数据进行测试; B) 不允许根据代码/错误/数据内容进行搜索;和many more reasons。除了代码格式的文本之外,只有在图像添加了一些重要的东西,而不仅仅是文本代码/错误/数据传达的内容时,才应该使用图像。
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多