【问题标题】:Primefaces 5.1 Dialog Framework dialogReturn event handler not calledPrimefaces 5.1 对话框框架 dialogReturn 未调用事件处理程序
【发布时间】:2014-11-14 19:51:12
【问题描述】:

我是 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?");
  }

对话框中接受命令按钮的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);
  }

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

【问题讨论】:

    标签: jsf-2 primefaces


    【解决方案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()");
    

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

    【讨论】:

    • 感谢您的建议。我有一个基于此的版本。我仍然有一种强烈的智力渴望,想知道为什么框架不起作用。
    【解决方案2】:

    我看到你经常使用 rendered="..." 属性。根据我的经验,&lt;p:ajax event="dialogReturn" /&gt; 不会在其自身或父元素未呈现时被触发。

    所以看看你的public void accept() 方法。如果您更改某些状态,以便&lt;p:ajax event="dialogReturn" /&gt; 的父元素(即rendered="#{!grantManager.hasAccess(ss)}" 和/或rendered="#{identity.loggedIn}")的渲染属性将评估为false,则不会执行侦听器。


    编辑

    我想到了一个解决方法。可以使用与从&lt;p:menuitem /&gt; (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>
    

    【讨论】:

      猜你喜欢
      • 2014-01-22
      • 2020-06-28
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      • 2017-06-04
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多