2017-05-11 4 views
0

프로젝트가 JBoss Seam 2.3, JSF 2.1 및 richfaces를 사용하여 빌드됩니다. richface aj4 호출을 사용하여 컴포넌트를 다시 렌더링 할 때 완전히 이해하지 못하는 부분이 있습니다.Seam 2.3 + JSF + AJAX. 다른 패널의 한 패널 메소드를 다시 렌더링 할 때

a4j를 사용하여 일부 동작이 실행되고 render 속성의 값이 일부 h : panelGroup id를 가리키는 경우 다른 패널의 메서드도 호출됩니다.

나는 이것을 증명할 수있는 몇 가지 코드를 준비했다.

BeanA.java. 데이터 액세스를 시뮬레이션합니다.

package test; 

import java.util.Arrays; 
import java.util.List; 

import org.jboss.seam.ScopeType; 
import org.jboss.seam.annotations.Logger; 
import org.jboss.seam.annotations.Name; 
import org.jboss.seam.annotations.Scope; 
import org.jboss.seam.log.Log; 

@Scope(ScopeType.CONVERSATION) 
@Name("beanA") 
public class BeanA { 

    @Logger 
    private Log log; 

    public List<Integer> list() { 
     log.info("beanA.list()"); 
     // DB Query simulation 
     Integer[] result = {1,2,3}; 
     return Arrays.asList(result); 
    } 

} 

BeanB.java. 간단한 클릭 카운터.

<f:view xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:a="http://richfaces.org/a4j" 
    xmlns:richext="http://java.sun.com/jsf/composite/richext" 
    xmlns:s="http://jboss.org/schema/seam/taglib" contentType="text/html" 
     xmlns:c="http://java.sun.com/jsp/jstl/core"> 
    <h:html> 
    <h:head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
     <title>TEST</title> 
    </h:head> 
    <h:body> 

     <h:panelGroup id="listPanel"> 
      <ul> 
       <li> 
        <h:outputText value="a:repeat" /> 
       </li> 
       <a:repeat value="#{beanA.list()}" var="i"> 
        <li> 
         <h:outputText value="#{i}" /> 
        </li> 
       </a:repeat> 
      </ul> 
<!--   <ul> --> 
<!--    <li> --> 
<!--     <h:outputText value="ui:repeat" /> --> 
<!--    </li> --> 
<!--    <ui:repeat value="#{beanA.list()}" var="i"> --> 
<!--     <li> --> 
<!--      <h:outputText value="#{i}" /> --> 
<!--     </li> --> 
<!--    </ui:repeat> --> 
<!--   </ul> --> 
<!--   <ul> --> 
<!--    <li> --> 
<!--     <h:outputText value="c:foreach" /> --> 
<!--    </li> --> 
<!--    <c:forEach items="#{beanA.list()}" var="i"> --> 
<!--     <li> --> 
<!--      <h:outputText value="#{i}" /> --> 
<!--     </li> --> 
<!--    </c:forEach> --> 
<!--   </ul> --> 
     </h:panelGroup> 

     <h:form> 
      <a:commandLink value="Dumb action" action="#{beanB.dumbAction()}" 
       execute="@this" render="timesDumbActionPanel" /> 
     </h:form> 

     <h:panelGroup id="timesDumbActionPanel"> 
      <h:outputText value="#{beanB.counter}" /> 
     </h:panelGroup> 
    </h:body> 
    </h:html> 
</f:view> 

내가 페이지 /test.seam beanA.list()를로드

package test; 

import org.jboss.seam.ScopeType; 
import org.jboss.seam.annotations.Logger; 
import org.jboss.seam.annotations.Name; 
import org.jboss.seam.annotations.Scope; 
import org.jboss.seam.log.Log; 

@Scope(ScopeType.CONVERSATION) 
@Name("beanB") 
public class BeanB { 

    @Logger 
    private Log log; 

    private int counter = 0; 

    public void dumbAction() { 
     // do nothing 
     log.info("beanB.dumbAction()"); 
     counter++; 
    } 

    public int getCounter() { 
     return counter; 
    } 

    public void setCounter(int counter) { 
     this.counter = counter; 
    } 

} 

test.xhtml 번이라고합니다. "Dumb action"링크를 클릭하면 다음과 같이 기록됩니다.

19:28:21,461 INFO [test.BeanA] (http--0.0.0.0-80-1) beanA.list() 
19:28:21,461 INFO [test.BeanB] (http--0.0.0.0-80-1) beanB.dumbAction() 
19:28:21,461 INFO [test.BeanA] (http--0.0.0.0-80-1) beanA.list() 

beanA.list()가 두 번 호출되어 이유를 알 수 없습니다. ui : repeat를 사용하는 경우 : repeat beanA.list()가 11 번처럼 호출됩니다. 나는 또한 스코프를 변경하려했지만 결과는 동일했습니다.

예상되는 동작은 beanB.dumbAction()을 호출하고 카운터를 새로 고치려면 패널을 다시 렌더링하는 것입니다.

나는 getter가 여러 번 호출된다는 것을 알고 있지만 이것은 모든 메소드에도 적용 되는가?

내가 이것을 피하기 위해 수행하는 작업은 목록에 대한 필드를 만들고, getter를 수정하여 초기화되지 않은 경우 초기화하는 것입니다. 다만 OK입니다

@Name("beanA") 
public class BeanA { 

    @Logger 
    private Log log; 

    private List<Integer> list; 

    public void initList() { 
     log.info("beanA.list()"); 
     // DB Query simulation 
     Integer[] result = { 1, 2, 3 }; 
     setList(Arrays.asList(result)); 
    } 

    public List<Integer> getList() { 
     if (list == null) 
      initList(); 
     return list; 
    } 

    public void setList(List<Integer> list) { 
     this.list = list; 
    } 

} 

이 게터가 여전히라고하지만 initList() : 이런 식으로 뭔가. 이 방법을 사용하면 필 요한 것보다 더 많은 쿼리를 실행하지 않아도됩니다. 유일한 문제는 데이터가 변경 될 때입니다. 수동으로 initList()를 다시 호출해야하는데, 패널을 다시 렌더링하는 것만으로는 충분하지 않습니다.

어쩌면 JSF 라이프 사이클 또는 기타 무언가를 놓친 것일 수 있습니다.이 문제에 대한 힌트를 제공해 주시겠습니까? 고맙습니다!!

답변

0

나는 getter가 여러 번 호출된다는 것을 알고 있지만 이것은 모든 메소드에도 적용 되는가?

JSF는 특정 메소드가 getter라는 것을 알고 있습니다. 데이터를 요청하는 장소 (예 : @value는 getter입니다.

getter를 여러 번 호출하는 이유는 JSF/RichFaces가 특정 요소를 찾고있을 때 모든 요소를 ​​거쳐야하기 때문입니다. 귀하의 경우 timesDumbActionPanel을 찾으려면 listPanel을 거치고 a4j:repeat을 확인해야합니다.

유일한 문제는 데이터가 변경 될 때입니다. 수동으로 initList()를 다시 호출해야하는데, 패널을 다시 렌더링하는 것만으로는 충분하지 않습니다.

initList()은 데이터를 변경하는 모든 방법에서 호출 할 수 있습니다.

관련 문제