组件在JSF中迭代和呈现嵌套的树状对象结构 [英] Component to iterate and render a nested tree-like object structure in JSF

查看:160
本文介绍了组件在JSF中迭代和呈现嵌套的树状对象结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定类定义如下:

  public class注释{

String username;
String comment;
List< Comment>回复

// ...
}

使用构造一个JSF页面,它以如下的树形结构呈现 Comment 实例中包含的数据?

 注释
UserOne说
blah blah
----
UserThree回复
blah blah blah
----
UserThree回答
blah blah blah
----
UserTwo说
blah blah
----
UserOne说
blah blah


解决方案

如果嵌套只有一级深度,或者具有固定的最大深度,那么你可以嵌套JSF中继器组件,如< ui:repeat> < h:dataTable>

 < ul> 
< ui:repeat value =#{bean.comments}var =comment>
< li>#{comment.username}#{comment.comment}
< ul>
< ui:repeat value =#{comment.replies}var =reply>
< li>#{reply.username}#{reply.comment}< / li>
< / ui:repeat>
< / ul>
< / li>
< / ui:repeat>
< / ul>

但是如果嵌套级别是unlimited,那么你需要一个JSF组件,树层次。这在标准JSF组件集中不可用。您需要查看第三方组件库,如 PrimeFaces < p:tree> RichFaces < rich:tree> OmniFaces < o:tree> 。 OmniFaces一个允许你完全控制树标记,而对于其他人,你可能需要使用一些好的CSS来使它看起来像你想要的。

 < o:tree value =#{bean.comments}var =comment> 
< o:treeNode>
< ul>
< o:treeNodeItem>
< li>#{comment.username}#{comment.comment}
< o:treeInsertChildren />
< / li>
< / o:treeNodeItem>
< / ul>
< / o:treeNode>
< / o:tree>

为了清楚起见,我只能重命名 String comment 属性到消息文本 orso。



如果你已经在JSF 2.x,那么考虑< my:comments comment =#{bean.comments}> 复合组件,如下所示。

 < cc:interface componentType =commentsComposite> 
< cc:attribute name =commenttype =com.example.Commentrequired =true/>
< / cc:interface>
< cc:implementation>
< c:if test =#{not empty cc.comment.replies}>
< ul>
< c:forEach items =#{cc.comment.replies}var =commentvarStatus =loop>
< li>
#{comment.username}#{comment.comment}
< my:comments comment =#{cc.parent.comment.replies [loop.index]}/>
< / li>
< / c:forEach>
< / ul>
< / c:if>
< / cc:implementation>

  @FacesComponent(commentsComposite)
public class CommentsComposite extends UINamingContainer {

private comment comment;

@Override
public void setValueExpression(String name,ValueExpression expression){
if(comment.equals(name)){
setComment expression.getValue(getFacesContext()。getELContext()));
}
else {
super.setValueExpression(name,expression);
}
}

public Comment getComment(){
return comment;
}

public void setComment(Comment comment){
this.comment = comment;
}

}

复合组件的递归树。 p>

Given the class definition below:

public class Comment {

    String username;
    String comment;
    List<Comment> replies;

    // ...
}

Is it possible to use construct a JSF page which renders data contained in a Comment instance in a tree like structure as follows?

Comments
UserOne said
blah blah
----
    UserThree replied
    blah blah blah
    ----
    UserThree replied
    blah blah blah
----
UserTwo said
blah blah
----
UserOne said
blah blah

解决方案

If the nesting is only one level deep, or has a fixed amount of maximum depth, then you could just nest JSF repeater components like <ui:repeat> or <h:dataTable> in each other the usual way.

<ul>
    <ui:repeat value="#{bean.comments}" var="comment">
        <li>#{comment.username} #{comment.comment}
            <ul>
                <ui:repeat value="#{comment.replies}" var="reply">
                    <li>#{reply.username} #{reply.comment}</li>
                </ui:repeat>
            </ul>
        </li>
    </ui:repeat>
</ul>

But if the nesting level is "unlimited", then you need a JSF component instead which can render a tree hierarchy. This is not available in standard JSF component set. You'd need to look at 3rd party component libraries like PrimeFaces <p:tree>, or RichFaces <rich:tree>, or OmniFaces <o:tree>. The OmniFaces one allows you to have full control over the tree markup, while for the others you'd possibly need to fiddle with some good CSS to get it to look like as you want.

<o:tree value="#{bean.comments}" var="comment">
    <o:treeNode>
        <ul>
            <o:treeNodeItem>
                <li>#{comment.username} #{comment.comment}
                    <o:treeInsertChildren />
                </li>
            </o:treeNodeItem>
        </ul>
    </o:treeNode>
</o:tree>

I'd for clarity only rename String comment property to message or text orso.

If you're already on JSF 2.x, then consider a <my:comments comment="#{bean.comments}"> composite component like below.

<cc:interface componentType="commentsComposite">
    <cc:attribute name="comment" type="com.example.Comment" required="true" />
</cc:interface>
<cc:implementation>
    <c:if test="#{not empty cc.comment.replies}">
        <ul>
            <c:forEach items="#{cc.comment.replies}" var="comment" varStatus="loop">
                <li>
                    #{comment.username} #{comment.comment}
                    <my:comments comment="#{cc.parent.comment.replies[loop.index]}" />
                </li>
            </c:forEach>
        </ul>
    </c:if>
</cc:implementation>

@FacesComponent("commentsComposite")
public class CommentsComposite extends UINamingContainer {

    private Comment comment;

    @Override
    public void setValueExpression(String name, ValueExpression expression) {
        if ("comment".equals(name)) {
            setComment((Comment) expression.getValue(getFacesContext().getELContext()));
        }
        else {
            super.setValueExpression(name, expression);
        }
    }

    public Comment getComment() {
        return comment;
    }

    public void setComment(Comment comment) {
        this.comment = comment;
    }

}

See also the blog on the subject, recursive tree of composite components.

这篇关于组件在JSF中迭代和呈现嵌套的树状对象结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆