私のプロジェクトは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のライフサイクルなどで何かを見逃しているかもしれませんが、これについていくつかのヒントを教えてください。ありがとうございました!!