具有lazyloading和rowexpansion的数据表在打开展开时给出了错误的对象



我使用的是一个带有lazyload的普通数据表和带有嵌套表的行扩展,在lazyload之后打开行扩展时遇到了问题。ScrollRows设置为150。

<ui:composition template="/ressources/basic.xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<ui:define name="title">#{label['template.tab1']}</ui:define>
<ui:define name="content">
<h:form id="crateTbl">
<p:dataTable  rowExpandMode="single" id="cTbl" var="crate" value="#{cratesView.lazyModel}" selectionMode="single" 
filteredValue="#{cratesView.filteredCrates}" selection="#{cratesView.selectedCrate}" 
lazy="true" liveScroll="true" scrollRows="150" 
widgetVar="cratesTbl" rowKey="#{crate.id}" scrollable="true" scrollHeight="550">
<p:column style="width:16px" exportable="false">
<p:rowToggler />
</p:column>
<p:column headerText="#{label['crate.col.grp']}" filterStyle="width:60px;" filterBy="#{crate.grp}" filterMatchMode="contains" width="60">
<h:outputText value="#{crate.grp}"/>
</p:column>
...additional columns of crate.
<p:rowExpansion >
<p:panelGrid columnClasses="label,value" >
<div class="remark-label"><b>#{label['crateview.toggle.remark']}</b>: <h:outputLabel value="#{crate.remark}"/></div>
<p:dataTable id='bTbl' var="bottle" value="#{cratesView.getBottles2Crate(crate)}"
widgetVar="bottleTbl" rowKey="#{bottle.id}" scrollable="true" scrollHeight="300">
<p:column headerText="#{label['bottle.col.grp']}" width="50">
<h:outputText value="#{bottle.grp}"/>
</p:column>
...additional columns of bottle
</p:dataTable>
</p:column>    
</p:row>
</p:panelGrid>  
</p:rowExpansion>
</p:dataTable>
</h:form>
</ui:define>  

和Bean:

@ManagedBean(name = "cratesView")
@ViewScoped
public class CrateView implements Serializable {
//object definitions
@PostConstruct
public void init() {
//init some objects
lazyModel = new LazyCrateDatamodel(cratesList);
}
public LazyDataModel<Crate> getLazyModel() {
return lazyModel;
}
public void setLazyModel(LazyCrateDatamodel lazyModel){
this.lazyModel = lazyModel;
}
public void setSelectedCrate(final Crate c){
this.selectedCrate = c;
}
public Crate getSelectedCrate() {
return this.selectedCrate;
}
public List<Crate> getFilteredCrates() {
return filteredCrates;
}
public void setFilteredCrates(List<Crate> filteredCrates) {
this.filteredCrates = filteredCrates;
}
public List<Bottle> getBottles2Crate(final Crate c)
{
int grp = c.getGrp(); //
return gProvider.getBottlesByCrate(calculated.getGrp(), 0);
}
}

在第一页上一切都很好,打开展开显示表中的正确数据。在加载接下来的150行并滚动回例如第一行并打开扩展之后,加载错误板条箱的数据cratesView.getBottles2Crate(crate(是用一个移动n*150(n-装载次数(的crate对象调用的。行切换事件的对象与数据模型的对象不同。在另一侧setSelectedCrate获取正确的对象。我是不是有什么配置错误,或者文档中有使用rowexpansion和lazyloading的提示。。。

谢谢你的提示。

编辑:更正一些语法。

很抱歉缺少信息:

Mojarra JSF实施2.3.0(20170310-1214(

Primeface 6.2

我用一个最小的版本进行了并行测试:

<?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 lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Lazy Test</title>
<link rel="icon" href="imgs/favicon.ico" type="image/x-icon" />
</h:head>
<body>
<h:form id="crateTbl">
<p:dataTable  rowExpandMode="single" id="cTbl" var="crate" value="#{lazyView.model}" selectionMode="single"  selection="#{lazyView.selectedCrate}" 
lazy="true" liveScroll="true" scrollRows="150" 
widgetVar="cratesTbl" rowKey="#{crate.id}" scrollable="true" scrollHeight="550">
<p:column style="width:16px" exportable="false">
<p:rowToggler />
</p:column>
<p:column headerText="Kistengrp" width="60">
<h:outputText value="#{crate.grp}"/>
</p:column>
<p:column headerText="Kistennamen" width="250">
<h:outputText value="#{crate.name}"/>
</p:column>
<p:column headerText="Flaschengrp" width="100">
<h:outputText value="#{crate.bgrp}"/>
</p:column>
<p:rowExpansion >
<p:panelGrid  columnClasses="label,value" >
<p:dataTable id='bTbl' var="bottle" value="#{lazyView.getBottlesByCrate(crate)}" widgetVar="bottleTbl" rowKey="#{bottle.id}" scrollable="true" scrollHeight="300">
<p:column headerText="Gruppe" width="50">
<h:outputText value="#{bottle.grp}"/>
</p:column>
<p:column headerText="Name" width="250">
<h:outputText value="#{bottle.name}"/>
</p:column>
<p:column headerText="Id" width="100">
<h:outputText value="#{bottle.id}"/>
</p:column>
</p:dataTable>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
</h:form>
</body>
</html>

类别:测试数据提供商:

package de.test;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
@ManagedBean(name = "testservice")
@ApplicationScoped
public class AssortmentProvider {
private final static String[] NAMES = {"Uerige","Koelsch","Wasser","Saft","Limo","Cola","Kupfer","Messing"};
private final static int[] BGRPS = {1,12,15,20,24,25,26,30,100,112,155,200,201,242,250};
private final static int[] CGRPS = {1000,1020,1050,2000,2400,2500,2600,3000,1006,1120,1550,2050,2010,2420,2500};
private List<Crate> crates;
private List<Bottle> bottles;
@PostConstruct
public void init() {
this.createBottles();
this.createCrates();
}
public List<Crate> getCrates() { return crates; }
public List<Bottle> getBottles() { return bottles; }
public List createCrates() {
crates = new ArrayList<>();
for(int i=0;i<500;i++) {
int n = (int) (Math.random() * 8);
int g = (int) (Math.random() * 15);
int b = (int) (Math.random() * 15);
Crate c = new Crate(NAMES[n], i, CGRPS[g]);
c.setBgrp(BGRPS[b]);
crates.add(c);
}
return crates;
}
public List createBottles() {
bottles = new ArrayList<>();
for(int i=0;i<500;i++) {
int n = (int) (Math.random() * 8);
int b = (int) (Math.random() * 15);
Bottle btl = new Bottle("B_" + NAMES[n], i, BGRPS[b]);
bottles.add(btl);
}
return bottles;
}
}

实体板条箱:

package de.test;
public class Crate extends Entity {
private int bgrp;
public Crate(String name, int id, int cgrp) { super(name,id,cgrp); }
public int getBgrp() { return bgrp; }
public void setBgrp(int bgrp) { this.bgrp = bgrp; }
@Override
public String toString() { return "Crate{" + "name=" + name + ", id=" + id + ", grp=" + grp + ", bgrp=" + bgrp +'}'; }
}

下一瓶:

package de.test;
public class Bottle extends Entity {
public Bottle(String name, int id, int grp) { super(name,id,grp); }
@Override
public String toString() { return "Bottle{" + "name=" + name + ", id=" + id + ", grp=" + grp + '}'; }
}

下一个实体:

package de.test;
public class Entity {
protected String name;
protected int id;
protected int grp;
public Entity(String name, int id, int grp) {
this.name = name;
this.id = id;
this.grp = grp;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public int getGrp() { return grp; }
public void setGrp(int grp) { this.grp = grp; }
}

下一个LazyView:

package de.test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
@ManagedBean(name = "lazyView")
@ViewScoped
public class LazyView implements Serializable {
@ManagedProperty("#{testservice}")
AssortmentProvider service;
List<Crate> crateList;
Crate selectedCrate;
LazyCrateModel model;
@PostConstruct
public void init() {
crateList = this.service.createCrates();
model = new LazyCrateModel(crateList);
}
public void setService(AssortmentProvider service) { this.service = service; }
public Crate getSelectedCrate() { return selectedCrate; }
public void setSelectedCrate(Crate selectedCrate) { this.selectedCrate = selectedCrate; }
public List<Crate> getCrateList() { return crateList; }
public void setCrateList(List<Crate> crateList) { this.crateList = crateList; }
public LazyCrateModel getModel() { return model; }
public List<Bottle> getBottlesByCrate(final Crate c) {
System.out.println(c);
List<Bottle> l = new ArrayList<>();
for(Bottle b : service.getBottles())
{
if( b.getGrp() == c.getBgrp())
l.add(b);
}
return l;
}
}

下一个LazyData模型:

package de.test;
import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
public class LazyCrateModel extends LazyDataModel<Crate> {
private final List<Crate> list;
public LazyCrateModel(List<Crate> list) { this.list = list; }
@Override
public Integer getRowKey(Crate object) { return object.getId(); }
@Override
public List<Crate> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
this.setRowCount(list.size());
if(first + pageSize > list.size()) {
pageSize = list.size() - first;
}
List<Crate> sub = list.subList(first, first + pageSize);
return sub;
}
@Override
public Crate getRowData(String str) {
int idx = Integer.parseInt(str);
for(Crate c : list) {
if(c.getId() == idx)
return c;
}
return null;
}
}

这是相同的行为:在一次加载滚动到开始后,给定的板条箱是150个移位的板条箱,而不是板条箱[0]。希望有人能证实这种行为。

最新更新