2012-05-23 1 views
5

JSF 2 기반 응용 프로그램에는 (다른 UI 구성 요소 사이에) 일부 확인란이 들어있는 양식이 있습니다.유효성 검사 오류 후 이후 ajax 요청은 Beans가 아닌 UI 구성 요소에서 값을 가져옵니다.

확인란을 선택하면 요청시 아약스 요청을 등록했습니다. Ajax 요청은 실제로 뒷받침 빈의 다른 체크 박스 값을 업데이트 할 것이다. 그 결과 다른 체크 박스도 체크됩니다 (렌더링 응답 단계에서 백킹 빈에서 업데이트 된 값을 취함에 따라 리 렌더링됩니다).

전체 양식이 제출되고 유효성 검사 오류가 발생할 때까지 제대로 작동합니다. 그런 다음 ajax 요청은 여전히 ​​작동하고 백킹 빈의 값을 변경하지만 업데이트 된 체크 박스를 다시 렌더링하는 단계에서는 백킹 빈에서 값을 가져 오지 않고, ComponentStateHelper 클래스에서 가져온 캐시 된 값을 값으로 사용합니다.

필자가 알고있는 한, JSF 2의 새로운 기능은 컴포넌트 트리의 부분적인 변경 사항 만 저장하는 데 사용됩니다.

내가 이해할 수없는 것은 : 이것은 검증 단계와 어떤 관련이 있습니까? 왜 유효성 검사에서 오류가 발견되면 StateHelper 클래스에 내 체크 박스가 캐시 된 값이 있습니까?

답변

4

이것은 알려진 문제이며 this answer에 깊이 설명되어 있습니다. 간단히 말해서 <f:ajax execute>에 의해 실행되지 않은 <f:ajax render>에 의해 렌더링 될 무효화 된 구성 요소가 원래 제출 된 값과 함께 무효화 된 상태로 유지되기 때문에 문제가 발생합니다. JSF가 입력 구성 요소를 렌더링 할 때 JSF는 먼저 제출 된 값이 null이 아닌지 확인한 다음 표시합니다. 그렇지 않으면 모델 값이 표시됩니다. 기본적으로 렌더링 될 입력 구성 요소의 제출 된 값을 재설정해야하지만 이는 ajax에 의해 실행되지 않습니다.

이를 달성하기 위해, 당신은 ActionListener 기본적으로 는 다음을 수행 사용할 수 있습니다

UIViewRoot viewRoot = context.getViewRoot(); 
PartialViewContext partialViewContext = facesContext.getPartialViewContext(); 
Set<EditableValueHolder> inputs = new HashSet<EditableValueHolder>(); 

// First find all to be rendered inputs and add them to the set. 
findAndAddEditableValueHolders(partialViewContext.getRenderIds(), inputs); 

// Then find all executed inputs and remove them from the set. 
findAndRemoveEditableValueHolders(partialViewContext.getExecuteIds(), inputs); 

// The set now contains inputs which are to be rendered, but which are not been executed. Reset them. 
for (EditableValueHolder input : inputs) { 
    input.resetValue(); 
} 

JSF issue 1060로보고되었으며 완전하고 재사용 가능한 솔루션 ResetInputAjaxActionListenerOmniFaces 라이브러리에 구현되었습니다 (소스 코드 here 및 쇼케이스 데모 here).

+0

답장을 보내 주셔서 감사합니다. 어쨌든 (FullAjaxExceptionHandlerFactory'의 경우) 이미 내 프로젝트에 omnifaces lib를 포함 시켰습니다. 따라서'faces-config.xml' 파일에'ResetInputAjaxActionListener'를 포함시키는 것은 쉽습니다. 그러나 이것은 InvoiceApplicationPhase'에서만 호출됩니다.이 InvokeApplicationPhase는 내 ajax 요청에 의해 적중되지 않습니다. 내 아약스 요청은'와''에 의해 실행됩니다. 하지만이 부분을 자세히 살펴 보겠습니다. 방금 당신의 제안을 신속하게 시도했습니다. – Jens

+0

맞지 않았습니까? 확실합니까? faces-config를 편집 한 후에 서버를 다시 시작해야 할 수도 있습니다. – BalusC

+0

나는 그것을 재시작했고 omnifaces의 소스를 추가하고 중단 점을 설정하여 충돌이 발생하는지 확인했습니다. 정기적 인 요청에는 적용되지만 체크 박스 선택에 의해 트리거되는 아약스 요청에는 적용되지 않습니다. – Jens