2014-11-14 89 views
0

我是JSF和primefaces的新手。我正在使用Primefaces对话框来弹出服务协议的模态条款。我遇到的问题是,当对话框关闭时,不会调用dialogReturn事件处理程序,尽管对话框本身关闭,模态叠加层仍保留在页面上。模态覆盖可能是一个红鲱鱼,因为dialogReturn方法在对话不是模态时也不会调用。Primefaces 5.1对话框框架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?"); 
    } 

actionLis在该对话框中的接受命令按钮特纳代码:

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); 
    } 

什么我的文档中错过?或者这是一个错误?

回答

0

我认为你可以尝试使用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()"); 

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

+0

感谢您的建议。我有一个基于此的版本。我仍然渴望知道为什么框架无法正常工作。 – 2014-11-14 23:28:19

0

我看你工作了很多与rendered="..."属性。从我体验到的<p:ajax event="dialogReturn" />没有被触发,如果它本身或父元素不呈现。

所以看看你的public void accept()方法。如果您更改某个状态,以致<p:ajax event="dialogReturn" />的一个父元素(即rendered="#{!grantManager.hasAccess(ss)}"和/或rendered="#{identity.loggedIn}")的渲染属性将评估为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>