2012-07-23 2 views
1

내가 이상한 행동을 가지고 실패 2 다음 페이지의 : 그 페이지 (또한 피포 페이지)을 선택하면 pilotNoTemplate.xhtml 또는 pipo.xhtml이 동적으로 페이지 양식을 먼저 제출 포함이 동적으로 페이지</p> <p>내 첫 페이지를 포함하는 다른 페이지에서 선택할 수있는 콤보가 포함에

@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가 제대로 나타납니다.

그러나 pilotNoTemplate.xhtml에서 양식을 제출할 때 JSF는 해당 게시물을 POST로 간주합니다. 이는 이지만 Phase1과 Phase 6만이 스팬되어 있습니다. 왜 그렇습니까? 내가 위상을 보여주는 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 

,이 resetted됩니다 ...

두 번째 제출하는 모든 권리, 모든 단계는 스팬 있습니다 :

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> 

에 제공이 이후 XHTML 페이지 의 모든 구성 요소 "ID" 그것 없이는 그런 종류의 문제가되고, 내 경우에는 불완전한 것으로 보인다. 아이디어가 있으십니까?

동일한 문제가있는 다른 사용자를 보았습니다. 해결책을 찾았습니까?

답변

0

이것은 JSF spec issue 790으로, JSF 2.0/2.1에서 발생하며 곧 출시 될 JSF 2.2에서 수정 된 버그로 인해 발생합니다. 기본적으로 JSF ajax가 현재 <h:form> 구성 요소 외부에서 <h:form> 구성 요소를 자식으로 포함하고 있으면 뷰 상태가 업데이트되지 않습니다 (이것은 감독 임). 그것은 아약스 업데이트에서 폼 컴포넌트를 명시 적으로 지정할 때만 업데이트됩니다. 이론적으로는 <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를 시도했지만 두 번 이상 실행하지 않는 것 ... 올바른 위치가 아닐 수있는 템플릿의 에 넣습니다. 나는 그것을 어디에 두어야합니까?<: 명령 단추 ID = "쇼"값 = "표시 페이지"H> \t \t \t \t

+0

좋아, 내가 any.xhtml \t'code' \t \t에서 AJAX 콜백에서 스크립트를 배치 "command = button"> "code =" "실행 ="@ 형식 "렌더링 =": panelForDynaPage : globalMessages "onevent ="jsf.ajax.addOnEvent "/> \t \t \t 첫 번째 해결책은 viewParam이 설정되어 있지 않고 # {pilotAction.prepare}가 호출되지 않은 것과 같습니다. –