我在这里和网上搜索并尝试了各种各样的东西; prependId,使用完整的id路径(:form:panelid:componentid kinda thing)和其他路径。
我仍然感到困惑。我还是一个JSF菜鸟:)
我的问题是,我在f:ajax渲染部分中指定的不是唯一部分得到“执行”。我的意思是,渲染中指定的id不会在屏幕上重新呈现,但会调用该组件的值。
所以:
inputText的f:ajax render = outA event = blur
当模糊发生时,调用outA的getter并重新渲染,但也会调用其他组件的getter,但它们不会被重新渲染。
具体而言,根据下面列出的代码:
A)当val1失去焦点时,它会触发模糊事件,它会调用getValue1()并重新渲染outval1。快乐。但是,getStuff()也被调用(它也适用于其他模糊和btnCalc)但是getStuff()的结果不会呈现给tblStuff dataTable。 为什么呢?
如何修复它,以便在blur事件中,只执行与render =“..”组件相关的getter?
我应该使用不同的部分吗?
B)当点击刷新按钮时,它将调用getStuff AGAIN,现在显示新的dataTable /即具有在模糊事件和btnReload点击事件期间添加的所有多个ValueTO的新数据。
C)对于在A中命名的任何一个事件,getStuff方法被正好调用8次。即,在输入框内单击,单击外部输入框,getStuff()* 8。 然而,getValue1只被调用了两次?
D)那里有任何好的JSF2书籍吗?以下是页面:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Stuff</title>
</h:head>
<h:body>
<h:form id="frmTrxMain" prependId="true">
<h1>
Stuff
</h1>
<h:dataTable title="Stuff" id="tblStuff" var="s" value="#{bean.stuff}" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{s.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{s.name}" />
</h:column>
</h:dataTable>
<h:outputText value="No stuff to display" rendered="#{empty bean.stuff}"/>
<h:commandButton value="Refresh" id="btnReload">
<f:ajax render="tblStuff" event="click"/>
</h:commandButton>
<hr/>
<h:panelGrid columns="3" id="pnlTwo">
<h:outputLabel value="Value1"/>
<h:inputText value="#{bean.value1}" id="val1">
<f:ajax event="blur" render="outVal1"/>
</h:inputText>
<h:outputText id="outVal1" value="Entered: #{bean.value1}" />
<h:outputLabel value="Value2"/>
<h:inputText value="#{bean.value2}" id="val2">
<f:ajax event="blur" render="outVal2"/>
</h:inputText>
<h:outputText id="outVal2" value="Entered: #{bean.value2}" />
<h:commandButton value="Calc" id="btnCalc">
<f:ajax event="click" render="outSum"/>
</h:commandButton>
</h:panelGrid>
<h:outputLabel id="outSum" value="#{bean.sum}"/>
</h:form>
</h:body>
</html>
支持bean:
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean(name = "bean")
@SessionScoped
public class TestStuffBean {
private int id=1;
private String name="a";
//test.xhtml
private String value1;
private String value2;
private List<TestVO> stuff = new ArrayList<TestVO>();
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
public String getSum() {
String result = "";
int sum;
try {
sum = Integer.parseInt(value1) + Integer.parseInt(value2);
result = Integer.toString(sum);
} catch (NumberFormatException e) {
result = "Enter two integers";
}
return result;
}
public List<TestVO> getStuff() {
//the VO is just a POJO with a contructor that takes
//two strings and a getter/setter for each id and name
stuff.add(new TestVO(Integer.toString(id), name+id));
id++;
return stuff;
}
}
答案 0 :(得分:0)
我不是JSF 2专家,因为我们仍在使用1.2但是我猜他们在这里有相同的属性:经常调用getter,例如在还原视图阶段重建视图时。因此,您不能仅依赖于仅为实际渲染的部件调用的getter。事实上,你不应该在你的getter中做任何昂贵的操作(比如db访问) - 在大多数情况下你不知道它们在一个循环中实际被调用的频率。
特别是你的getStuff()
方法应该改变,让一个getter引起副作用,例如添加到内部列表中的东西,就像在这种情况下一样,也几乎总是糟糕的设计。
编辑:澄清对getter的评论:
通常情况下,getter不应该执行昂贵的操作,因为您不知道JSF调用它们的频率。
由于您仍然需要从某些源(如数据库)获取某些数据,因此您可能只提供方法(如loadDataFromDB()
)并填充托管bean中的某些数据结构。然后,getter可能只是提供该数据结构。
您可以添加对未初始化的数据结构的检查,如果没有在getter中调用load方法,但我只将其用作最后一个选项。通常,您应该能够单独调用加载方法,例如通过单击刷新按钮或导航到页面 - 这就是我们的工作。