p:在分页LazyDataModel之后丢失dataTable选项 [英] p:dataTable selections are lost after paginating a LazyDataModel

查看:122
本文介绍了p:在分页LazyDataModel之后丢失dataTable选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是,在我选择了第一页上的几个项目之后,如果我分页到另一个页面并返回,我的初始选择不会显示。我试图实现 SelectableDataModel 以及使用 rowKey 属性,但问题仍然存在。



这是我的测试bean:

  @ManagedBean 
@ViewScoped
public class MrBean {
private List< Item> selectedItems;
private LazyDataModel lazyModel;

@PostConstruct
public void prepareTest(){
this.lazyModel = new LazyItemDataModel();
}

public void countItems(){
System.out.println(TEST 3:selectedItems's size:+ selectedItems.size());
}

private class LazyItemDataModel extends LazyDataModel< Item>实现SelectableDataModel< Item> {
@Override
public Item getRowData(String rowKey){
System.out.println(TEST 1:getRowData);
迭代器< Item> iter =((List< Item>)this.getWrappedData())。iterator();
while(iter.hasNext()){
项目项= iter.next();
if(item.getId()。equals(rowKey)){
return item;
}
}

返回null;
}

@Override
public Object getRowKey(Item item){
return item.getId();
}

@Override
public List< Item> load(int first,int pageSize,String sortField,SortOrder sortOrder,Map filters){
System.out.println(TEST 2:load);
//从数据库中获取项目的代码
}
}

// Getters和Setters
}

这是我的测试页:

  ;?xml version ='1.0'encoding ='UTF-8'?> 
<!DOCTYPE html PUBLIC - // W3C // DTD XHTML 1.0 Transitional // ENhttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
< html xmlns =http://www.w3.org/1999/xhtml
xmlns:h =http://java.sun.com/jsf/html
xmlns:p =http://primefaces.org/ui>
< h:head>
< title>测试页< / title>
< / h:head>
< h:body>
< h:form>
< p:dataTable id =itemTablevar =itemvalue =#{mrBean.items}rows =5
paginator =trueselection =#{mrBean。 selectedItems}lazy =true>

< p:ajax event =rowSelectCheckboxlistener =mrBean.countItems/>

< p:列selectionMode =multiple/>

< p:column headerText =ID>
< h:outputText value =#{item.id}/>
< / p:column>

< p:column headerText =Name>
< h:outputText value =#{item.name}/>
< / p:column>

< / p:dataTable>
< / h:form>
< / h:body>
< / html>

如果您能告诉我我在这里做错了什么,我将非常感激。 p>

更新:添加更多 System.out.println(TEST)上面的代码,我观察到以下事情:


  1. 在控制台上,每次我分页, TEST 1:总是在 TEST 2:load 之前打印getRowData 。因此,我相信方法#LazyDataModel.getWrappedData()可能会从旧页返回数据。起初,我认为这个方法的目的是检索选中的行以突出显示在表上。但是,如果在加载之前调用此方法,那么没有办法可以正常工作?

  2. 在我选择了第1 2第一页上的项目,在控制台上,我看到 TEST 3:selectedItems的大小:2 。如果我分页到第二页,然后回到第一页,选择将丢失如上所述。但是,如果我继续选择另一个项目,在控制台上,我看到 TEST 3:selectedItems的大小:3 。显然, selectedItems 列表仍然保留了我的旧选择,但没有呈现在表格上。


解决方案

只需实现绑定到DataTable的选择属性的属性( selection =#{pageBackingForm.selectedEntityList} )这样做,它将工作:

 私有地图<整数,列表&实体>> selectedEntityListMap = new Hashtable<>(); 

public List< Entity> getSelectedEntityList(){
return selectedEntityListMap.get(getCurrentEntitySelectionPage());
}

public void setSelectedEntityList(List< Entity> selectedEntityList){
if(selectedEntityList == null){
selectedEntityListMap.remove(getCurrentEntitySelectionPage());
return;
}

selectedEntityListMap.put(getCurrentEntitySelectionPage(),selectedEntityList);
}

public Integer getCurrentEntitySelectionPage(){
DataTable dataTable =(DataTable)FacesContext.getCurrentInstance()。getViewRoot()。findComponent(formId:dataTableId);
return dataTable.getPage();
}


My problem is that after I've selected a few items on the 1st page, if I paginate to another page and come back, my initial selections are not shown. I've tried to implement the SelectableDataModel as well as using the rowKey attribute but the problem persists.

This is my test bean:

@ManagedBean
@ViewScoped
public class MrBean {
    private List<Item> chosenItems;
    private LazyDataModel lazyModel;

    @PostConstruct
    public void prepareTest() {
        this.lazyModel = new LazyItemDataModel();
    }

    public void countItems() {
        System.out.println("TEST 3: chosenItems's size: " + chosenItems.size());
    }

    private class LazyItemDataModel extends LazyDataModel<Item> implements SelectableDataModel<Item> {
        @Override
        public Item getRowData(String rowKey) {
            System.out.println("TEST 1: getRowData");
            Iterator<Item> iter = ((List<Item>) this.getWrappedData()).iterator();
            while (iter.hasNext()) {
                Item item = iter.next();
                if (item.getId().equals(rowKey)) {
                    return item;
                }
            }

            return null;
        }

        @Override
        public Object getRowKey(Item item) {
            return item.getId();
        }

        @Override
        public List<Item> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters) {
            System.out.println("TEST 2: load");
            // Code to retrieve items from database
        }
    }

    // Getters and Setters
}

This is my test page:

<?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:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Test page</title>
    </h:head>
    <h:body>
        <h:form>
            <p:dataTable id="itemTable" var="item" value="#{mrBean.items}" rows="5" 
                         paginator="true" selection="#{mrBean.chosenItems}" lazy="true" >

                <p:ajax event="rowSelectCheckbox" listener="mrBean.countItems" />                    

                <p:column selectionMode="multiple" />

                <p:column headerText="ID">
                    <h:outputText value="#{item.id}" /> 
                </p:column>

                <p:column headerText="Name">
                    <h:outputText value="#{item.name}" /> 
                </p:column>

            </p:dataTable>
        </h:form>
    </h:body>
</html>

I'd be very grateful if you could show me what I've done wrong here.

UPDATE: After I added more System.out.println("TEST") to the above code, I observed the following things:

  1. On the console, every time I paginate, TEST 1: getRowData is always printed before TEST 2: load. As a consequence, I believe the method #LazyDataModel.getWrappedData() may return data from the old page. At first, I thought this method's goal was to retrieve the selected rows to highlight on the table. However, if this method is called before load, there's no way it can do the job right?
  2. After I selected the 1st 2 items on the 1st page, on the console, I saw TEST 3: chosenItems's size: 2. If I paginate to the 2nd page and then back to the 1st page, the selections are lost as mentioned. However, if I continued to select another item, on the console, I saw TEST 3: chosenItems's size: 3. Obviously, the chosenItems list still kept my old selections but they're not rendered on the table.

解决方案

Just implement the property bound to selection property of DataTable (selection="#{pageBackingForm.selectedEntityList}") like this and it will work :

    private Map<Integer, List<Entity>> selectedEntityListMap = new Hashtable<>();

    public List<Entity> getSelectedEntityList() {
        return selectedEntityListMap.get(getCurrentEntitySelectionPage());
    }

    public void setSelectedEntityList(List<Entity> selectedEntityList) {
        if (selectedEntityList == null) {
            selectedEntityListMap.remove(getCurrentEntitySelectionPage());
            return;
        }

        selectedEntityListMap.put(getCurrentEntitySelectionPage(), selectedEntityList);
    }

    public Integer getCurrentEntitySelectionPage() {
        DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("formId:dataTableId");
        return dataTable.getPage();
    }

这篇关于p:在分页LazyDataModel之后丢失dataTable选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆