我正在尝试实现一个页面,该页面根据输入上的key up事件触发的backing bean方法的结果显示/隐藏元素。我写的内容非常出乎意料 - 我的panelGroup中的内容在页面加载后根本不会改变,而是在页面顶部出现一个包含我期望在outputText元素中显示的内容的狂野跨度。这是在JSF 1.2和richfaces 3.3上运行的遗留应用程序,因此可能无法使用此功能(见here)。我也为表的使用道歉,但遗憾的是重构这个大的旧应用程序以使用适当的布局与css / divs超出了这个功能请求的范围。
这是我的示例jstl模板,它说明了问题。 “string1 / 2颠倒”输出面板应仅显示字符串长度是否大于5,并且输入时输入时应更新outputText元素中的文本。相反,outputPanel保持静态,并在表格上方创建新的范围。
<!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:c="http://java.sun.com/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<head>
<title>ajax test</title>
</head>
<body>
<h:panelGroup id="wrapper">
<a4j:keepAlive beanName="AjaxTestBacking" />
<p />
<h:form>
<table>
<tr>
<td >string1:</td>
<td>
<h:inputText style="width: 200px" value="#{AjaxTestBacking.string1}">
<a4j:support event="onkeyup" action="#{AjaxTestBacking.updateString1}" reRender="string1panel"/>
</h:inputText>
</td>
</tr>
<h:panelGroup id="string1panel" rendered="#{AjaxTestBacking.displayString1Xform}">
<tr>
<td>string1 reversed:</td>
<td>
<h:outputText style="width: 200px" value="#{AjaxTestBacking.string1Xform}" />
</td>
</tr>
</h:panelGroup>
<tr>
<td>string2:</td>
<td>
<h:inputText style="width: 200px" value="#{AjaxTestBacking.string2}">
<a4j:support event="onkeyup" action="#{AjaxTestBacking.updateString2}" reRender="string2panel"/>
</h:inputText>
</td>
</tr>
<h:panelGroup id="string2panel" rendered="#{AjaxTestBacking.displayString2Xform}">
<tr>
<td>string2 reversed:</td>
<td >
<h:outputText style="width: 200px" value="#{AjaxTestBacking.string2Xform}" />
</td>
</tr>
</h:panelGroup>
</table>
</h:form>
</h:panelGroup>
</body>
</html>
和支持bean:
import java.io.Serializable;
@SuppressWarnings("serial")
public class AjaxTestManager extends AbstractManager implements Serializable {
private String string1;
private String string2;
private String string1Xform;
private String string2Xform;
private Boolean displayString1Xform;
private Boolean displayString2Xform;
public AjaxTestManager() {
string1 = "test string 1";
string2 = "test string 2";
updateString1();
updateString2();
}
public void updateString1() {
string1Xform = new StringBuilder(string1).reverse().toString();
displayString1Xform =string1Xform.length() > 5 ? true : false;
}
public void updateString2() {
string2Xform = new StringBuilder(string2).reverse().toString();
displayString2Xform = string2Xform.length() > 5 ? true : false;
}
public String getString1() {
return string1;
}
public void setString1(String string1) {
this.string1 = string1;
}
public String getString2() {
return string2;
}
public void setString2(String string2) {
this.string2 = string2;
}
public String getString1Xform() {
return string1Xform;
}
public void setString1Xform(String string1Xform) {
this.string1Xform = string1Xform;
}
public String getString2Xform() {
return string2Xform;
}
public void setString2Xform(String string2Xform) {
this.string2Xform = string2Xform;
}
public Boolean getDisplayString1Xform() {
return displayString1Xform;
}
public void setDisplayString1Xform(Boolean displayString1Xform) {
this.displayString1Xform = displayString1Xform;
}
public Boolean getDisplayString2Xform() {
return displayString2Xform;
}
public void setDisplayString2Xform(Boolean displayString2Xform) {
this.displayString2Xform = displayString2Xform;
}
}
如果我在这里从根本上误解了有关richfaces的内容,我道歉 - 我有点喜欢富有表面的ajax,所以请耐心等待!我与构建应用程序的同事分享了这段代码,他也很难过。我在google和SO上搜索并找到了一个基于javascript的答案,但我试图了解如何使用richfaces组件来做到这一点。其他问题:“呈现”属性是否可以通过动态显示/隐藏页面部分来实现,或者我应该使用“可见”属性?另外,是a4j上的'reRender'属性:支持应该是我最初理解的元素的jsf /'服务器端'id,还是所示的呈现的客户端元素ID here?只是想弄清楚我是否误解了某些东西,受到我的jsf / richfaces版本的限制,或者只是一般都疯了:)
答案 0 :(得分:0)
我见过与JSF 2.1类似的行为。如果某个元素上存在呈现的标记,并且您计划通过ajax显示/隐藏该元素,则应该使用另一个命名容器将其包装并重新呈现父容器。这样的事情可以做到
<tr>
<td >string1:</td>
<td>
<h:inputText style="width: 200px" value="#{AjaxTestBacking.string1}">
<a4j:support event="onkeyup" action="#{AjaxTestBacking.updateString1}" reRender="string1panelLabel,string1panelValue"/>
</h:inputText>
</td>
</tr>
<tr>
<td>
<h:panelGroup id="string1panelLabel">
<h:panelGroup rendered="#{AjaxTestBacking.displayString1Xform}">
string1 reversed:
</h:panelGroup>
</h:panelGroup>
</td>
<td>
<h:panelGroup id="string1panelValue">
<h:panelGroup rendered="#{AjaxTestBacking.displayString1Xform}">
<h:outputText style="width: 200px" value="#{AjaxTestBacking.string1Xform}" />
</h:panelGroup>
</h:panelGroup>
</td>
</tr>
<tr>
请注意,panelGroup在这里渲染一个span,结果不是合法的html,因为tr标签之间不能存在span。相反,panelGroup应该在表中的td标记内。因此,您必须有两组嵌套的panelGroup来解决问题。或者,你可以用h:panelGrid替换html表,它生成一个html但对JSF更友好。
作为旁注,我在JSF 2.1中使用ui:fragment,因为它使得显示/隐藏屏幕的这一部分的意图比panelGroup更明显。