2012-07-23 33 views
1

我有一個奇怪的行爲上動態地包含動態地包含的頁面形式先提交失敗

我的第一頁有一個組合,從不同的頁面選擇包括:

 <h:panelGrid columns="2"> 
      <h:outputLabel value="Choose your page to include" /> 
      <h:selectOneMenu id="pageList" value="#{anyPageBean.page}"> 
       <f:selectItems value="#{anyPageBean.pageList}" var="w" itemValue="#{w}" itemLabel="#{w}" /> 
      </h:selectOneMenu> 
     </h:panelGrid> 

的AnyPageBean只是給回一個的2個以下頁面:pilotNoTemplate.xhtml或pipo.xhtml

@ManagedBean 
@SessionScoped 
public class AnyPageBean { 

private String page; 
private java.util.List<String> pageList; 

public AnyPageBean() { 
    super(); 
    pageList = new ArrayList<String>(); 
    pageList.add("pilotNoTemplate.xhtml"); 
    pageList.add("pipo.xhtml"); 
} 

的pilotNoTemplate.xhtml當我選擇頁面(該頁面PIPO也)正確顯示。

但是,當我從pilotNoTemplate.xhtml提交表單時,JSF認爲提交的POST爲OK, 但是隻有Phase1和Phase6跨越,爲什麼? 我展示一個階段的PhaseListener,它打印:

INFO IN pour /jsf2-todo-001-dynamic-page-include-v2/any.faces ¤¤¤¤¤ POST 
INFO AJAX BEFORE RESTORE_VIEW 1 for viewId=null 
INFO AJAX AFTER RESTORE_VIEW 1 for viewId=/any.xhtml 
INFO AJAX BEFORE RENDER_RESPONSE 6 for viewId=/any.xhtml 
INFO AJAX AFTER RENDER_RESPONSE 6 for viewId=/any.xhtml 

如果有什麼事情是在製作填充,它就會被重置了......

第二提交的所有權利,所有的階段都跨越:

INFO IN pour /jsf2-todo-001-dynamic-page-include-v2/any.faces ¤¤¤¤¤ POST 
INFO AJAX BEFORE RESTORE_VIEW 1 for viewId=null 
INFO AJAX AFTER RESTORE_VIEW 1 for viewId=/any.xhtml 
INFO AJAX BEFORE APPLY_REQUEST_VALUES 2 for viewId=/any.xhtml 
INFO AJAX AFTER APPLY_REQUEST_VALUES 2 for viewId=/any.xhtml 
INFO AJAX BEFORE PROCESS_VALIDATIONS 3 for viewId=/any.xhtml 
INFO AJAX AFTER PROCESS_VALIDATIONS 3 for viewId=/any.xhtml 
INFO AJAX BEFORE UPDATE_MODEL_VALUES 4 for viewId=/any.xhtml 
INFO AJAX AFTER UPDATE_MODEL_VALUES 4 for viewId=/any.xhtml 
INFO AJAX BEFORE INVOKE_APPLICATION 5 for viewId=/any.xhtml 
INFO AJAX AFTER INVOKE_APPLICATION 5 for viewId=/any.xhtml 
INFO AJAX BEFORE RENDER_RESPONSE 6 for viewId=/any.xhtml 
INFO AJAX AFTER RENDER_RESPONSE 6 for viewId=/any.xhtml 

我的模板頁面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> 
<h:head> 
    <meta http-equiv="Cache-Control" content="no-store" /> 
    <meta http-equiv="Pragma" content="no-cache" /> 
    <meta http-equiv="Expires" content="0" /> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
</h:head> 
<h:body> 
    <div> 
     <h:panelGroup id="globalMessages"> 
      <h:messages globalOnly="false" styleClass="messages" /> 
     </h:panelGroup> 
     <ui:insert name="content" /> 
    </div> 
</h:body> 
</html> 

合作mposition頁面,從而能夠選擇一個頁面,包括:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" > 

<ui:composition template="/layout/template.xhtml"> 
    <ui:define name="content"> 
     <h:form id="chooseForm"> 
      <h:panelGrid columns="2"> 
       <h:outputLabel value="Choose your page to include" /> 
       <h:selectOneMenu id="pageList" value="#{anyPageBean.page}"> 
        <f:selectItems value="#{anyPageBean.pageList}" var="w" itemValue="#{w}" itemLabel="#{w}" /> 
       </h:selectOneMenu> 
      </h:panelGrid> 
      <h:commandButton id="show" value="Show page"> 
       <f:ajax event="click" execute="@form" render=":panelForDynaPage :globalMessages" /> 
      </h:commandButton> 
     </h:form> 

     <h:panelGroup id="panelForDynaPage"> 
      <ui:include id="includeContenu" src="#{anyPageBean.page}" /> 
     </h:panelGroup> 

    </ui:define> 
</ui:composition> 
</html> 

的pilotNoTemplate.xhtml頁:

<?xml version="1.0" encoding="UTF-8"?> 
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> 
    <f:metadata> 
     <f:viewParam id="b" name="id" value="#{pilotAction.id}" /> 
    </f:metadata> 
    <f:event id="a" listener="#{pilotAction.prepare}" type="preRenderView" /> 

    <h:form id="formPilot"> 
     <h:panelGrid columns="2"> 
      <h:outputLabel value="#{appMsg['pilot.firstname']}" /> 
      <h:inputText id="firstname" label="#{appMsg['pilot.firstname']}" value="#{pilotHolder.pilot.firstname}" 
       required="true" /> 
      <h:outputLabel value="#{appMsg['pilot.lastname']}" /> 
      <h:inputText id="lastname" label="#{appMsg['pilot.lastname']}" value="#{pilotHolder.pilot.lastname}" /> 
      <h:outputLabel value="#{appMsg['pilot.age']}" /> 
      <h:inputText id="age" label="#{appMsg['pilot.age']}" value="#{pilotHolder.pilot.age}" required="true" 
       validator="#{pilotAction.validateAge}" /> 
     </h:panelGrid> 
     <h:commandButton id="merge" action="#{pilotAction.doMerge}" 
      value="#{pilotHolder.pilot.id ne null ? appMsg['pilot.update'] : appMsg['pilot.create']}"> 
      <f:ajax id="ajaxm" event="click" execute="@form" render=":panelForDynaPage :globalMessages" /> 
     </h:commandButton> 
    </h:form> 
</ui:composition> 

我關注給予「ID」的每一個組件的XHTML頁面, 因爲如果沒有它,這種問題似乎對我來說不太好。 有什麼想法?

我看過別人有同樣的問題,你有沒有找到解決辦法?

回答

0

這是由JSF spec issue 790引起的,這是JSF 2.0/2.1中發生的一個錯誤,並在即將發佈的JSF 2.2中修復。基本上,當JSF ajax在當前<h:form>之外更新時,組件又包含另一個子組件,則其視圖狀態將不會更新(這是一個疏忽)。只有在您明確指定ajax更新中的表單組件時纔會更新它。你理論上可以通過<h:panelGroup id="panelForDynaPage">代替<h:form id="panelForDynaPage">來解決它,但這在技術上是錯誤的標記。

您可以使用以下JS來修復此錯誤。此腳本將爲在ajax更新後未檢索任何視圖狀態的表單創建javax.faces.ViewState隱藏字段。

var ie = /*@[email protected]*/false; 

jsf.ajax.addOnEvent(function(data) { 
    if (data.status == "success") { 
     var viewState = document.getElementsByName("javax.faces.ViewState")[0].value; 

     for (var i = 0; i < document.forms.length; i++) { 
      var form = document.forms[i]; 

      if (!hasViewState(form)) { 
       var hidden = document.createElement(ie ? "<input name='javax.faces.ViewState'>" : "input"); 
       hidden.setAttribute("type", "hidden"); 
       hidden.setAttribute("name", "javax.faces.ViewState"); 
       hidden.setAttribute("value", viewState); 
       hidden.setAttribute("autocomplete", "off"); 
       form.appendChild(hidden); 
      } 
     } 
    } 
}); 

function hasViewState(form) { 
    for (var i = 0; i < form.elements.length; i++) { 
     if (form.elements[i].name == "javax.faces.ViewState") { 
      return true; 
     } 
    } 

    return false; 
} 
+0

感謝您的回答。我嘗試了用替換並從所包含的頁面中刪除 = solution1,提交正常,但不起作用。 ..我試過的JS,但它似乎並沒有執行多次......我把它放在模板的這可能不是正確的位置。我應該在哪裏放置它? – 2012-09-04 13:43:23

+0

好吧,我放置在AJAX回調的腳本any.xhtml \t'code' \t \t \t \t \t \t \t \t \t'code'。它具有相同的pb有第一個解決方案:未設置viewParam並且未調用#{pilotAction.prepare}。 – 2012-09-07 06:58:54