在 JSF 中迭代和呈现嵌套的树状对象结构的组件 [英] Component to iterate and render a nested tree-like object structure in JSF
问题描述
鉴于下面的类定义:
public class Comment {
String username;
String comment;
List<Comment> replies;
// ...
}
是否可以使用构造一个 JSF 页面来呈现包含在 Comment
实例中的数据的树状结构,如下所示?
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
推荐答案
如果嵌套只有一层深度,或者有固定的最大深度,那么你可以嵌套 JSF 中继器组件,如 <ui:repeat>
或
以通常的方式相互连接.
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>
但是如果嵌套级别是无限",那么您需要一个 JSF 组件来代替它可以呈现树层次结构.这在标准 JSF 组件集中不可用.您需要查看 3rd 方组件库,例如 PrimeFaces
或 RichFaces
,或 OmniFaces
.OmniFaces 允许您完全控制树标记,而对于其他标记,您可能需要调整一些好的 CSS 以使其看起来像您想要的那样.
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>
为了清楚起见,我只将 String comment
属性重命名为 message
或 text
左右.
I'd for clarity only rename String comment
property to message
or text
orso.
如果您已经在使用 JSF 2.x,那么请考虑使用 <my:comments comment="#{bean.comments}">
复合组件 如下所示.
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;
}
}
另见关于该主题的博客,recursive复合组件树.
See also the blog on the subject, recursive tree of composite components.
这篇关于在 JSF 中迭代和呈现嵌套的树状对象结构的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!