我试图通过编写一个小的“树”组件来更好地掌握JSF2内部结构,该组件采用节点结构并将其呈现为简单的ul / li元素。
应该可以定义Way,叶子的内容有点像这样呈现(类似于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);
}
}
}
}
为了简化,我首先开始使用一个简单的字符串ArrayList并迭代地打印出内容。这是xhtml:
<custom:tree value="#{testBean.strings}" var="testdata">
<h:outputText value="#{testdata}" />
</custom:tree>
那么,实现这一目标的正确方法是什么?
祝你好运, ChristianVoß
答案 0 :(得分:1)
感谢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);
}
}
}