여기에서 설명 할 것보다 더 큰 문제가 있습니다. 그러나 설명하고 디버깅하기가 어려울 수 있으므로 더 작은 및 벙어리) 문제가 발생합니다.전용 Java 클래스가있는 사용자 정의 컴포넌트에서 Ajax 뷰 업데이트가 제대로 작동하지 않습니다.
내 목록에서 문자열 목록을 인쇄하려고하는데이 목록은 오프셋을 기반으로 계산됩니다. 내 자바 클래스에서 나는 거대한 정적 배열의 문자열 있습니다. 내 문자열 목록 (페이지에 인쇄 될)을 계산하려면 정적 배열의 값을 "offset"값부터 시작하여 내 목록에 복사합니다.
내 페이지에는 아약스 요청을 통해 "오프셋"값을 증가시키고 결과를 업데이트하는 "오프셋 증가"버튼이 있습니다 (목록은 새 오프셋을 기준으로 다시 계산됩니다).
내 문제는 : "Increment offset"버튼을 클릭하면 서버 측 코드가 실행되고 오프셋은 증가하지만 업데이트시 문제가 발생합니다 : 현재 오프셋을 보여주는 텍스트가 새 값으로 업데이트 됨 "offset"은 같지만 문자열 목록에는 동일하지 않으며 이전 값으로 업데이트되며 두 번째 요청을 수행하는 경우 새 값이 고려됩니다. 두 번째 요청에서 계산 된 값은 세 번째 업데이트에서는 뷰의 문자열 목록을 항상 한 요청 만 늦게 만듭니다.
이 이미지보기 (그래서 더 큰하는 새 탭에서 엽니) :
가의 몇 가지 코드를 보자 ...
버튼 : 문자열의
<h:form>
<h:commandButton value="Increment offsets">
<f:ajax listener="#{test.incrementOffset()}" render=":stringList" />
</h:commandButton>
</h:form>
목록 :
<h:panelGroup id="stringList">
<h1>Offsets increment = #{test.offset}</h1>
<comp:stringPrinter offset="#{test.offset}" />
</h:panelGroup>
내가 제목에 대해 이야기 한 구성 요소가 있습니다. 문자열 목록은 페이지에 의해 계산되거나 인쇄되지 않습니다. 복합 요소로 계산되고 인쇄됩니다.
@ManagedBean(name="test")
@ViewScoped
public class Test implements Serializable {
private int offset;
public int getOffset() {
return offset;
}
public void incrementOffset(){
offset++;
}
}
복합 구성 요소 :
복합 구성 요소의 코드에 가기 전에, 여기에 뷰에 사용 된 관리 빈 "테스트"의 간단한 말했듯이, 그것은 단지로 "오프셋"수신 매개 변수를 지정하고 문자열 목록을 인쇄하십시오. 아래 뷰 코드를 참조하십시오 :
<h:body>
<composite:interface componentType="stringPrinter">
<composite:attribute name="offset" type="java.lang.Integer" required="true" />
</composite:interface>
<composite:implementation>
<ul>
<ui:repeat value="#{cc.list}" var="string">
<li>#{string}</li>
</ui:repeat>
</ul>
</composite:implementation>
</h:body>
을 그리고 이것은 문자열의 목록을 계산하는 방법이다 : 나는 구성 요소를 사용하지 않는 경우
@FacesComponent(value="stringPrinter")
public class StringPrinter extends UINamingContainer implements Serializable {
private ArrayList<String> list;
private static String[] LIPSUM = "...".split(" "); // "..." is not the actual string, the string is irrelevant (it has more than 400 words separated by spaces).
private static int ARRAY_SIZE = 12;
private void generateList(){
int offset = (Integer) getAttributes().get("offset");
int position = offset;
list = new ArrayList<String>();
for (int i = 0; i < ARRAY_SIZE; i++){
list.add(LIPSUM[position++ % LIPSUM.length]);
}
}
public ArrayList<String> getList() {
if (null == list) generateList();
return list;
}
}
}
문제가 발생하지 않습니다. 상위 뷰에서 목록이 계산되고 구성 요소에 연결된 Java 클래스가없는 경우 문제가 발생하지 않습니다. 그러나 실제 문제는 문자열을 출력 할 필요가 없기 때문에 복합 컴포넌트로 처리해야 할 필요가 있으므로 전용 클래스가 필요합니다.
일부 디버깅 :
는 UI : 반복 태그가 문제가 될 수 있습니다. 목록에서 첫 번째 문자열을 인쇄해야하는 목록을 인쇄하는 대신 (ui : repeat가 필요할 것입니다.) 모든 항목이 올바른 시간에 올바르게 업데이트됩니다.반복 : 정말 UI를 사용해야
<h:body>
<composite:interface componentType="stringPrinter">
<composite:attribute name="offset" type="java.lang.Integer" required="true" />
</composite:interface>
<composite:implementation>
<h:outputText value="#{cc.list.get(0)}" />
</composite:implementation>
</h:body>
작품 위의 코드를하지만, 내가해야 할 일이 아니다 : 반복 : UI를 사용하지 않고 복합 구성 요소의 코드를 참조하십시오. 나는 또한 c : forEach, 같은 결과를 시도했다.
추가 디버깅을 위해 나는 페이지에서 incrementOffset() 메소드가 실행 된 후 구성 요소의 getList() 메소드가 호출되는지를 스스로에게 묻습니다. " 이 로그는 다음과 같습니다.
*** GET LIST CALLED!
*** GET LIST CALLED!
*** OFFSET INCREMENTED!
*** GET LIST CALLED!
*** GET LIST CALLED!
메시지가 버퍼되지 않도록 System.out.flush()를 사용했습니다. 메소드가 실행 된 후에 getList()가 호출 된 것처럼 보입니다. 뷰가 이전 값으로 업데이트되는 이유가 표시되지 않습니다. 어쨌든 incrementOffset()이 실행되기 직전에 두 번 호출되고 두 번 후에는 조금 이상하다는 사실이 사실입니다.
이 문제는 Mojarra 2.1.7, 2.1.22, 2.1.23 및 2.2.0에 영향을줍니다. 나는 다른 버전을 테스트하지 않았다.
추가 디버그로이 게시물을 업데이트 할 예정입니다.
은 Maven 프로젝트를 다운로드하고 자신을 위해 테스트하려면 다음 zip file감사합니다 사전에 어떤 대답을.
기꺼이 해결했습니다. – Andy
''은 ''안에있을 필요가 없습니다. –
BalusC