2012-06-06 30 views
3

呈现一个嵌套的树状对象结构下面给出的类定义:组件迭代和JSF

public class Comment { 

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

    // ... 
} 

是否有可能使用构建这使得在树上包含在Comment实例数据JSF页面如下结构?

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

回答

3

如果嵌套只有一个级别深,或具有最大深度的一个固定的量,那么你可以只窝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> 

但是,如果嵌套层次是“无限的”,那么你需要一个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属性重命名为messagetext公积金。

如果您已经使用JSF 2.x,请考虑下面的<my:comments comment="#{bean.comments}">composite component

<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; 
    } 

} 

又见关于这一主题的博客,recursive tree of composite components

0

您可以创建一个包装Comment的新类。它会有一个评论和一个深度属性。

public CommentWithDepth { 
    private Comment comment; 
    private int depth; 

    public CommentWithDepth(Comment comment, int depth) { 
     this.comment = comment; 
     this.depth = depth; 
    } 

    public Comment getComment() { 
     return comment; 
    } 
    public int getDepth() { 
     return depth; 
    } 
} 

然后创建CommentWithDepth的列表,以正确的顺序所有的意见,并在属性深度评论树为基础水平的深度(0,1为基础LEVE的孩子的,2为下一个,等等)。

现在您可以使用ui:repeat来渲染此列表,并使用depth属性确定缩进。