我正试图通过编写一个小的"树"组件来更好地掌握JSF2的内部结构,该组件采用节点结构并将其渲染为简单的ul/li元素。
应该可以定义方式,叶的内容呈现方式有点像这样(类似于h:DataTable(:
<custom:tree value="#{someBean.someListProperty}" var="nodeData">
<h:outputText value="#{nodeData}" />
...
</custom:tree>
目前,我正在努力弄清楚如何将该变量"填充"到当前上下文中。我试过这样的东西,但没有用:
@Override
@SuppressWarnings("unchecked")
public void encodeChildren(FacesContext context) throws IOException {
if ((context == null)){
throw new NullPointerException();
}
ArrayList<String> list = (ArrayList<String>) getStateHelper().eval("value");
String varname = (String) getStateHelper().eval("var");
if(list != null){
for(String str : list){
getStateHelper().put(varname, str);
for(UIComponent child: getChildren()){
child.encodeAll(context);
}
}
}
}
为了简化,我首先开始使用一个简单的字符串数组列表,并迭代地打印出内容。这是xhtml:
<custom:tree value="#{testBean.strings}" var="testdata">
<h:outputText value="#{testdata}" />
</custom:tree>
那么,实现这一目标的正确方法是什么呢?
谨致问候,Christian Voß
感谢BalusC,
简单地说,这基本上是我的问题的答案(或者更好的答案(:
您可以将给定键下的一个新变量放入requestMap,任何子组件都可以使用指定的ValueExpression访问它。
@Override
@SuppressWarnings("unchecked")
public void encodeChildren(FacesContext context) throws IOException {
if ((context == null)){
throw new NullPointerException();
}
ArrayList<String> list = (ArrayList<String>) getStateHelper().eval("value");
String varname = (String) getStateHelper().eval("var");
Map<String, Object> requestMap = context.getExternalContext().getRequestMap();
varStore = requestMap.get(varname); // in case this Object already exists in the requestMap,
// emulate "scoped behavior" by storing the value and
// restoring it after all rendering is done.
if(list != null){
for(String str : list){
requestMap.put(varname, str);
for(UIComponent child: getChildren()){
child.encodeAll(context);
}
}
// restore the original value
if(varStore != null){
requestMap.put(varname, varStore);
}else{
requestMap.remove(varname);
}
}
}