Primefaces 5.1 Dialog Framework dialogReturn事件处理程序未调用

时间:2014-11-14 19:51:12

标签: jsf-2 primefaces

我是JSF和primefaces的新手。我正在使用Primefaces对话框架来弹出模态的服务协议条款。我遇到的问题是,当对话框关闭时,我的dialogReturn事件处理程序不会被调用,并且虽然对话框本身关闭,但模态覆盖仍保留在页面上。模态叠加可能是红色鲱鱼,因为当对话框不是模态时,不会调用dialogReturn方法。

以下是相关的代码:

创建对话框的表单:

<h:form prependId="false">
<ul>
    <ui:repeat value="#{serviceEditor.service.subsystems}" var="ss">
    <li>
    <em>#{ss.name}</em> - #{ss.description}<br/>
    <ui:fragment rendered="#{identity.loggedIn}">
         <ui:fragment rendered="#{grantManager.hasAccess(ss)}">
                            (You have access to this dataset.)
             <h:commandButton value="Discontinue Access" action="#{grantManager.unrequestAccess(ss)}"/>
         </ui:fragment>
         <ui:fragment rendered="#{!grantManager.hasAccess(ss)}">
             <p:commandButton value="Request Access"
                       actionListener="#{serviceDialog.display(ss)}"
                       styleClass="btn btn-primary" >
                 <p:ajax event="dialogReturn" 
                         listener="#{serviceEditor.acceptDialogHandler}" />
             </p:commandButton>
          </ui:fragment>
...

ServiceEditor已注释@Named @Stateful @ConversationScoped

对话框显示的actionListener代码:

  public void display (ServiceSubsystem sub)
  {
    if (sub == null)
    {
      log.error("Service Accept dialog attempt with null subservice. Lose.");
      FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Subservice Unavailable", "We seem to have misplaced that service. This has been logged for investigation.");
      RequestContext.getCurrentInstance().showMessageInDialog(message);
      return;
    }
    log.info("svcDlg: Displaying accept dialog for service: {}.{}", sub.getService().getName(), sub.getName());
    this.sub = sub;
    Map<String, Object> dlgOpts = new HashMap<>(2);
    dlgOpts.put("modal", true);
    RequestContext.getCurrentInstance().openDialog("serviceAcceptDialog", dlgOpts, null);
    log.info("svcDlg: Did that accept dialog work out?");
  }

对话框中的accept命令按钮的actionListener代码:

  public void accept ()
  {
    log.info("Accepted {}.{}", sub.getService().getName(), sub.getName());
...
    String destination = "/service?faces-redirect=true&uuid=" + sub.getService().getUuid();
    log.info("Sending user to: {}", destination);
    RequestContext.getCurrentInstance().closeDialog(destination);
  }

最后,对话框返回未调用的侦听器:

  public void acceptDialogHandler (SelectEvent event)
  {
     String dest = (String) event.getObject();
     log.info("Service accept dialog closed. sending here: ", dest);
     ((ConfigurableNavigationHandler) FacesContext.getCurrentInstance().getApplication().getNavigationHandler())
            .performNavigation(dest);
  }

我在文档中遗漏了什么?或者这是一个错误吗?

2 个答案:

答案 0 :(得分:1)

我认为您可以尝试使用primefaces dialog component,更简单。

要显示或关闭对话框,您只需要调用它:

PF('widgetVarDialogName').hide();
PF('widgetVarDialogName').show();

您可以在查看操作中打开或关闭它,例如:

<p:commandButton
    value="Open dialog"
    type="button"
    onclick="PF('widgetVarDialogName').show()" />

<p:commandButton
    value="Do Action"
    action="#{myBean.myAction()}"
    oncomplete="PF('widgetVarDialogName').hide();" />

另外,如果需要,可以从bean调用它。

RequestContext.getCurrentInstance().execute("PF('widgetVarDialogName').show()");
RequestContext.getCurrentInstance().execute("PF('widgetVarDialogName').hide()");

(请记住,对话框必须放在表单中)

答案 1 :(得分:0)

我看到你使用rendered="..."属性做了很多工作。根据我的经验,<p:ajax event="dialogReturn" />如果没有呈现自身或父元素,则不会被触发。

请查看public void accept()方法。如果更改某个状态,以便<p:ajax event="dialogReturn" />的父元素(即rendered="#{!grantManager.hasAccess(ss)}"和/或rendered="#{identity.loggedIn}"的呈现的attirbute将评估为false,则不会执行该侦听器

修改

我想到了一个解决方法。可以使用相同的解决方法来避免问题,就像您想要从<p:menuitem />Primefaces Dialog Framework — dialogReturn event from menuitem)触发对话框架一样。

只需在可能未渲染的区域之外的某处创建一个单独的按钮,然后通过javascript触发它。

未经测试的代码示例:

<ui:fragment 
    id="fragment" 
    rendered="#{...}">
    <h:commandButton
        id="pseudo_button"
        value="..." 
        onclick="document.getElementById('real_button').click()" />
</ui:fragment>

<h:commandButton 
    id="real_button"
    action="#{bean.realWorkHere()}"
    update="fragment"
    style="display:none;">
    <p:ajax 
        event="dialogReturn" 
        listener="#{...}" />
</h:commandButton>