PrimeFaces DataTable 在延迟加载时出现奇怪的行为(视频内部;))



来自德国的晚上好!

我对PrimeFaces DataTable组件有一个非常奇怪的行为:

我有一个简单的pojo,一个从数据库中获取POJO的EJB,一个用于我的JSF页面的控制器和一个从Primefaces实现LazyDataModel的CDI Bean。一切都按预期工作。站点之间的分页正在工作,过滤器和排序。但是当我使用操作侦听器单击数据表行中的按钮时,一切都停止工作。分页不起作用(如果请求/响应已完成...很奇怪),直到我重新加载页面。

为了更好地理解,我做了一个小视频:

https://www.youtube.com/watch?v=B2PgQCNIVQc

我想,EJB 调用一定是问题所在,但我错了。我用一个简单的ArrayList做了一个小(非常快速和肮脏的;))示例,我能够重现这个(Primefaces 4.0.x和Primefaces 5-Snapshot):

起初,我的POJO:

public class User {
  private String login;
  private Date removeDate;
  public String getLogin() {
    return login;
  }
  public void setLogin(String login) {
    this.login = login;
  }
  public Date getRemoveDate() {
    return removeDate;
  }
  public void setRemoveDate(Date removeDate) {
    this.removeDate = removeDate;
  }
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof User)) return false;
    User user = (User) o;
    if (!login.equals(user.login)) return false;
    return true;
  }
  @Override
  public int hashCode() {
    return login.hashCode();
  }
}

非常简单的 ControllerBean with LazyLoad-Method 和 Action:

@Named
@SessionScoped
public class LazyUserBean implements Serializable {
  private List<User> userEntityList = new ArrayList<>();
  @PostConstruct
  public void init() {
    for (int i = 0; i < 100; i++) {
      User newUser = new User();
      newUser.setLogin("User " + i);
      newUser.setRemoveDate(new Date());
      userEntityList.add(newUser);
    }
  }
  public List<User> getAllEntitiesLazy(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters, boolean invalidate) {
    List<User> returnList = new ArrayList<>();
    for (int i = first; i < this.userEntityList.size(); i++) {
      returnList.add(this.userEntityList.get(i));
    }
    return returnList;
  }
  public void removeDelDate(User user) {
    user.setRemoveDate(null);
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
        Environment.getMessageResourceString("de.flatphormesmedia.wbsagentur.resources.lang_de", "persistence.recycleSuccess", new String[]{"bla"}), ""));
  }
}

LazyLoadModel-Implementation:

@Named
@ViewScoped
public class LazyUserModel extends LazyDataModel<User> implements Serializable {
  private List<User> datasource;
  @Inject
  LazyUserBean lazyUserBean;
  @Override
  public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
    this.datasource = this.lazyUserBean.getAllEntitiesLazy(first, pageSize, sortField, sortOrder, filters, true);
    this.setRowCount(100);
    return datasource;
  }
  @Override
  public Object getRowKey(User user) {
    return user.getLogin();
  }
}

最后是JSF页面:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://primefaces.org/ui ">
<h:head>
</h:head>
<h:body>
    <h:form id="formEditUsers">
        <p:dataTable value="#{lazyUserModel}" var="user" lazy="true" paginator="true"
                     rows="13" id="tableUsers" emptyMessage="#{langRes['editUsers.emptyTable']}"
                     paginatorPosition="top">
            <!-- user login column -->
            <p:column headerText="#{langRes['editUsers.colHeadLogin']}" id="columnLogin"
                      filterBy="#{user.login}"
                      sortBy="#{user.login}">
                <p:outputLabel id="labelLogin" value="#{user.login}"/>
            </p:column>
            <!--delete date column-->
            <p:column headerText="#{langRes['setupAddresses.colHeadDeleteDate']}" id="columnDeletedDate"
                      width="20%">
                <p:outputLabel id="labelDeletedDate" value="#{user.removeDate}">
                    <f:convertDateTime pattern="dd.MM.yyyy - HH:mm:ss"/>
                </p:outputLabel>
            </p:column>
            <!-- edit column -->
            <p:column id="columnEdit" width="10%" style="text-align: center">
                <p:commandButton actionListener="#{lazyUserBean.removeDelDate(user)}"
                                 update=":formEditUsers:tableUsers"
                                 process="@this" id="buttonRecycle" icon="ui-icon-arrowreturnthick-1-w"
                                 style="height: 70% !important">
                </p:commandButton>
            </p:column>
        </p:dataTable>
    </h:form>
</h:body>
</html>

正如我所说,非常快速和肮脏...但这里没有什么特别的。自上周六以来,这让我发疯了。我在这里做错了什么?或者这是一个PrimeFaces-Bug?简直不敢相信,我是第一个发现这种行为的人。提前感谢!

更新 1:我将 ajax="false" 属性添加到命令按钮,并且在完整请求下它就像一个魅力。按钮有什么问题吗?

这是一个素数错误。使用 r11009 (https://code.google.com/p/primefaces/source/detail?r=11009) 修复。

嗯,我以前从未见过LazyDataModel也是一个托管的bean。你的代码看起来不错,所以也许你应该尝试将模型和 Bean 分成不同的类。

请尝试process

=":formEditUsers:tableUsers"而不是process="@this"

最新更新