1

JSF 2.0 的 ui:repeat 标记获取 java bean(arraylist) 的值,因为它是 value 属性,但 size 属性没有。我在数据表中使用 ui repeat 迭代地显示状态,ui repeat 显示每个状态的注释。我从 java 类中给出了 ui repeat 的 size 属性,因为每个状态都有不同数量的注释。因此大小应该动态决定。这是我所做的总结。模型类:

@ManagedBean
@RequestScoped
public class Comment {
     private String commentAuthorName;
//getter and setter
}

这表示具有注释列表的 Status 类:

@ManagedBean
@RequestScoped
public class Status {
    private ArrayList<Comment> commentList;
    private int numOfComments;
//getter and setter
}

这是关于 StatusBean 类的一个想法:

@ManagedBean
@SessionScoped
public class StatusBean {
    List<Status> panelList = new ArrayList<Status>();
    List<Comment> commentList = new ArrayList<Comment>();
    public static void process() {
        panelList = StatusService.getPersonalStatus(log.getLoggeduser());//means fill list
        commentList = StatusService.getPersonalComments(panelList);//gets comments via related statuses
        for (int i=0; i<panelList.size(); i++) { //for each status
             Status status = panelList.get(i);
             for(Comment comment : commentList) { //for each comment of each status
             status.setNumOfCommentsShown(1);
           }
        }
    }
}

视图层如下所示。PrimeFaces DataTable 中包含的 UI 重复能够显示每个状态的每个评论。我正在使用数据表,因为它具有实时滚动功能,并且必须迭代地显示所有状态,并且 ui repeat 看起来最好显示每个状态的每个评论。

<p:dataTable liveScroll="true" value="#{StatusBean.panelList}" 
             var="Status" scrollable="true">
   <ui:repeat var="Comment" value="#{Status.commentList}" 
           size="#{Status.numOfComments}"></ui:repeat>
</p:dataTable>

调试结果显示 #{Status.numOfComments} 正确填充了预期的整数,但仍然无法正常工作。但是如果我手动编写 size=3 ,它会给出预期的结果。

4

1 回答 1

5

据我所知,直到今天还没有答案,所以我会回答你的问题,并就我肯定会在你的堆栈中改变的内容给你一些想法。

分析你的问题

<ui:repeat>关于托管 bean 属性指定的with属性的使用,我编写了与您类似的代码size,但它也不适用于我。无论我多么努力地尝试通过 EL 设置属性值,它都不起作用。此外,它也不适用于最简单的 EL #{5}。我不知道问题出在哪里,但我认为这里的经验会启发我们为什么会发生这种情况,对吗?

可能是JSF<ui:repeat>组件的故障,那么我们将提出一个关于它的问题。如果它是一个特性,那么完全理解它会很好。

据我了解,您的代码的一个工作示例

关于上面的代码,有很多简单的解决方法。如果您如此坚持使用该<ui:repeat>组件,我将为您提供基本的工作示例。您的视图层由一个 JSF 托管 bean 和两个模型类支持。我的解决方案使用<ui:param><ui:fragment>. 开始了。

风景:

<p:dataTable value="#{statusBean.statusesList}" var="status">
    <p:column headerText="Status name">
        <h:outputText value="#{status.statusName}"/>
    </p:column>
    <p:column headerText="Status comments">
        <ul>
            <ui:param name="max" value="#{status.numOfComments}"/>
            <ui:repeat var="comment" value="#{status.commentList}" varStatus="statusVar">
                <ui:fragment rendered="#{statusVar.index lt max}">
                    <li>
                        <h:outputText value="Author: #{comment.authorName}; comment: #{comment.description}"/>
                    </li>
                </ui:fragment>
            </ui:repeat>
        </ul>
    </p:column>
</p:dataTable>

该模型:

public class Comment {

    private String authorName;
    private String description;

}

public class Status {

    private List<Comment> commentList;
    private int numOfComments;
    private String statusName;

}

托管bean:

@ManagedBean
@RequestScoped
public class StatusBean {

    private List<Status> statusesList;

    public StatusBean() {
        Status status;
        List<Status> statusesList = new ArrayList<Status>();
        Comment comment;
        List<Comment> commentList;
        for(int s = 0; s < 10; s++) {
            commentList = new ArrayList<Comment>();
            for(int c = 0; c < 20; c++) {
                commentList.add(new Comment("User " + (s + 1) + "-" + (c + 1), "Description for comment " + (s + 1) + "-" + (c + 1)));
            }
            statusesList.add(new Status(commentList, (s + 1), "Status " + (s + 1)));
        }
        this.statusesList = statusesList;
    }

}

我肯定会在你的代码中改变的事情

代码运行后,我想说明我会做的一些改进。

  1. 使您的模型成为模型:摆脱@ManagedBean@...Scoped注释,并将它们(分离的)@Entity类改为,由您的服务 bean 钻研;
  2. 尝试使模型尽可能简单,同时保留应用程序的功能。我的示例仅使用状态列表作为 bean 中的数据持有者:您不需要重复的注释列表,因为它已经存在于Status对象中;
  3. 不要在 bean 中使用静态方法,而是在页面操作方法 (Servlet 3.0)、preRenderView侦听器 (Servlet 2.5) 或方法中(预)加载必要的数据@PostConstruct。好好选择 bean 范围。咨询BalusC 的出色概述将是一个很好的起点。
  4. 使用服务方法调用仅从数据源预加载您需要的数据:如果您愿意显示有限数量的评论,为什么要从您的数据源中获取它们?根据您的需要限制结果集(请记住,如果您想实现“查看全部”功能,您可以使用 ajax 更新您的元素并加载其余部分)。让它以这种方式工作就不需要使用size="...";
  5. 使用标准 UI 组件或您选择的组件库的组件,即 Primefaces,因此请尝试遵循 Luiggi Mendoza 的建议。

托管 bean 的示例启动示例如下:

@ManagedBean
@RequestScoped
public class StatusBean {

    private List<Status> statusesList;

    @EJB
    private StatusService statusService;

    @ManagedProperty(value="#{user}")
    private User user;

    @PostConstruct
    public void init() {
        statusesList = statusService.getStatuses(user);
    }

    public List<Status> getStatusesList() {
        return statusesList;
    }

}
于 2013-02-13T13:05:09.427 回答