【问题标题】:Jsf ui:repeat size doesn't gets java bean valueJsf ui:repeat size 不获取 java bean 值
【发布时间】:2013-01-27 20:14:05
【问题描述】:

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

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

这表示具有 cmets 列表的 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 ,它会给出预期的结果。

【问题讨论】:

  • 如果您想获得具体帮助,请发布您的代码的 sscce,否则没有人能够或想要回答您的问题。作为旁注,您的代码显示出对 Java 命名约定的一些不尊重,这可能会使一些读者拒绝回答。
  • 感谢您对实习生的有用评论。由于您的建议,我更新了我的问题顺便说一句我今天感觉不太好,对错误表示抱歉。
  • 我不明白你想在&lt;p:dataTable&gt; 中使用内部&lt;ui:repeat&gt; 来实现什么。您还有其他 PrimeFaces 组件可以帮助您喜欢 &lt;p:subTable&gt; 和 &lt;p:rowExpansion&gt;。
  • 我的意思是每个状态元素已经包含 cmets 列表,并且它们是实体类或 DTO,而不是托管 bean(具有请求范围)。接下来,会话范围 bean 的静态方法是一个非常糟糕的主意。最好在 post 构造方法或页面操作方法中填充值。此外,第二个列表的迭代是多余的,因为评论对象上没有方法调用。
  • 看答案,享受 JSF 的“隐藏”功能!

标签: jsf jsf-2 primefaces datatable uirepeat


【解决方案1】:

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

您的问题分析

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

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

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

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

观点:

<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 中的数据持有者:您不需要重复的 cmets 列表,因为它已经存在于 Status 对象中;
  3. 不要在 bean 中使用静态方法,而是在页面操作方法 (Servlet 3.0)、preRenderView 侦听器 (Servlet 2.5) 或 @PostConstruct 方法中(预)加载必要的数据。好好选择 bean 范围。咨询an excellent overview by BalusC 将是一个很好的起点;
  4. 使用服务方法调用仅从数据源预加载您需要的数据:如果您愿意显示有限数量的 cmets,为什么要从数据源中获取它们?根据您的需要限制结果集(请记住,如果您想实现“查看全部”功能,您可以使用 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;
    }

}

【讨论】:

  • 哇!这一定是这个问题能给出的最好答案了!!!我刚刚实现了您的代码,并且完全按照我想要的方式工作。当然,我会尝试考虑您的建议。当我完成实施时,我将分享经验。哇,我非常感谢这个优雅而出色的答案。
  • 我有一个与您的建议有关的问题here
  • 您好,我在 ace:dataTable 中实现了此解决方案,但 ui:repeat 不起作用。你可以在这里看到我的代码:stackoverflow.com/questions/26761221/…
猜你喜欢
  • 2015-07-04
  • 1970-01-01
  • 2017-06-01
  • 2012-02-29
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多