-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi
I'm having troubles with a listbox. I have a paging listbox that loads the items from database. One of my tables has 850000 records
All the records all load lazy, I only load the first 20 and when the user clicks on the next page or inputs the page number I load this records
To do the pagination I do a select count and assigns the size to the model (I defined a model to do that)
The pagination is fine and there is no problems with tables with less tan 10000 records. The problem is in ListboxDataLoader class. I have in my model 20 items but the ListboxDataLoader creates 850000 items in line 109:
for (; --newcnt >= 0; ++min) {
if (renderer == null)
renderer = (ListitemRenderer)getRealRenderer();
_listbox.insertBefore(newUnloadedItem(renderer, min), next);
}
I tried to set the render on demand attribute in the listbox but it doesn't works because the event onPaging calls the sync method on ListboxDataLoader and the 850000 items are created
Any ideas how to solve this?
Thanks in advance
you should use ROD(ZK EE's feature) or it will new 'skeleton' listitems to listbox (in your case, they are 850000), read the document here
Or, you could build pagination manually for the best performance(control all the detail), here is my example by MVVM + JPA
zul
<window apply="org.zkoss.bind.BindComposer" title="Manual Paging"
viewModel="@id('vm') @init('org.zkoss.jpa.examples.live.ManualPagingCatViewModel')"
border="normal" hflex="1" vflex="1" contentStyle="overflow:auto">
<hbox>
<vbox width="400px">
<paging
onPaging="@command('paging')"
totalSize="@bind(vm.totalSize)" pageSize="@bind(vm.pageSize)" activePage="@bind(vm.activePage)"/>
<listbox model="@bind(vm.availableCategories)"
selectedItem="@bind(vm.selectedCategory)" rows="@bind(vm.pageSize)">
<template name="model">
<listitem>
<listcell label="@load(each.name)" />
</listitem>
</template>
</listbox>
<paging
onPaging="@command('paging')"
totalSize="@bind(vm.totalSize)" pageSize="@bind(vm.pageSize)" activePage="@bind(vm.activePage)"/>
</vbox>
<vbox visible="@bind(not empty vm.selectedCategory)">
<label value="@bind(vm.selectedCategory.name)" />
<listbox model="@bind(vm.selectedCategory.items)">
<template name="model">
<listitem>
<listcell label="@load(each.name)" />
</listitem>
</template>
</listbox>
</vbox>
</hbox>
</window>
java
package org.zkoss.jpa.examples.live;
import java.io.Serializable;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.jpa.examples.entity.Category;
import org.zkoss.jpa.examples.service.CommonDao;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zkplus.spring.DelegatingVariableResolver;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;
@VariableResolver(DelegatingVariableResolver.class)
public class ManualPagingCatViewModel implements Serializable{
private static final long serialVersionUID = 1L;
@WireVariable
CommonDao commonDao;
Category selectedCategory;
ListModelList<Category> availableCategories;
int pageSize = 10;
int activePage = 0;
int totalSize;
public ListModel<Category> getAvailableCategories() {
return availableCategories;
}
public Category getSelectedCategory(){
return selectedCategory;
}
public int getActivePage() {
return activePage;
}
public void setActivePage(int activePage) {
this.activePage = activePage;
}
public int getPageSize() {
return pageSize;
}
public int getTotalSize() {
return totalSize;
}
public void setSelectedCategory(Category selectedCategory) {
if(selectedCategory!=null){
//refresh it to avoid org.hibernate.LazyInitializationException
this.selectedCategory = commonDao.reload(selectedCategory);
}else{
this.selectedCategory = null;
}
}
@init
public void init(){
totalSize = commonDao.sizeOf(Category.class);
availableCategories = new ListModelList(commonDao.list(Category.class,activePage*pageSize,pageSize));
}
@Command
@NotifyChange({"totalSize","availableCategories"})
public void paging(){
totalSize = commonDao.sizeOf(Category.class);
if(activePage*pageSize>=totalSize){//the data size was change since last paging, reysnc it.
activePage = 0;//simply to first page
}
availableCategories = new ListModelList(commonDao.list(Category.class,activePage*pageSize,pageSize));
}
}
Here is an online example with about 2.2 Million records. Paged on database.
best Stephan
PS: not optimzed for backward
Asked: 2013-02-15 07:50:18 +0800
Seen: 150 times
Last updated: May 08 '14
Are you using ROD?
sjoshi ( 2013-02-15 10:54:33 +0800 )editLook here
hswain ( 2013-02-20 10:44:53 +0800 )edit