【问题标题】:Custom Component: how to populate an ELContext Variable to rendered children自定义组件:如何填充 ELContext 变量以呈现子级
【发布时间】:2013-02-25 19:04:20
【问题描述】:

我试图通过编写一个小的“树”组件来更好地掌握 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);
            }
        }
    }
}

为了简单起见,我首先开始使用一个简单的字符串数组列表并迭代地打印出内容。这是xhtml:

<custom:tree value="#{testBean.strings}" var="testdata">
    <h:outputText value="#{testdata}" />
</custom:tree>

那么,实现这一目标的正确方法是什么?

最好的问候, 克里斯蒂安·沃斯

【问题讨论】:

  • 这是一个相当广泛的主题,所以这里只是一个基于 JSF 的开源树组件的链接,它应该提供一些见解:showcase.omnifaces.org/components/tree(您可以在底部找到源代码链接)跨度>

标签: jsf-2 custom-component


【解决方案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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2023-03-13
    • 2019-10-10
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多