2017-05-11 10 views
0

私のプロジェクトはJBoss Seam 2.3、JSF 2.1およびrichfacesを使用して構築されています。 richface aj4を使用してコンポーネントを再レンダリングするときに私が完全に理解していないことがあります。Seam 2.3 + JSF + AJAX。他のパネルの1つのパネルメソッドを再描画するときにも呼び出されます

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。シンプルクリックカウンタ。

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

<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を(ロード)を1回と呼ばれています。 2回呼び出されます)

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()を呼び出してカウンタを更新するためにパネルを再描画することです。

ゲッターが複数回呼び出されるのは分かりますが、これはすべてのメソッドにも当てはまりますか?

私がこれを避けるには、リストのフィールドを作成し、ゲッターを変更して、そうでなければ初期化するだけです。このようなもの:

@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; 
    } 

} 

getterはまだ呼び出されますが、initList()は正常ではありません。こうすることで、必要以上にクエリを実行することを避けることができます。唯一の問題は、データが変更されたときです。手動でinitList()をもう一度呼び出す必要があり、パネルを再レンダリングするだけでは不十分です。

多分私はJSFのライフサイクルなどで何かを見逃しているかもしれませんが、これについていくつかのヒントを教えてください。ありがとうございました!!

答えて

0

getterは何度も呼び出されますが、これはすべてのメソッドにも当てはまりますか?

JSFは、特定のメソッドがゲッターであることを知っているわけではありません。データを求める場所で使用している場合(例: @valueそれはゲッターです。

getterを複数回呼び出す理由は、JSF/RichFacesが特定の要素を探しているときに、その前にあるすべての要素を調べなければならないためです。あなたの場合、timesDumbActionPanelを見つけるためにはlistPanelを通過し、a4j:repeatをチェックしなければなりません。

唯一の問題は、データが変更された場合です。手動でinitList()をもう一度呼び出す必要があり、パネルを再レンダリングするだけでは不十分です。

initList()は、データを変更する方法から呼び出すことができます。

関連する問題