2014-11-14 92 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>