0

我正在使用带有延迟加载的普通数据表和带有嵌套表的行扩展,并且在延迟加载后打开行扩展时遇到问题。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>  

和豆:

@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 行并滚动回例如第一行并打开扩展后,将加载错误 crate 的数据。cratesView.getBottles2Crate(crate)被调用,箱子对象移动了 n*150(n - 加载次数)。rowtoggling-event 的对象与数据模型不同。另一方面,setSelectedCrate获取正确的对象。我是否配置错误或文档中是否有使用行扩展和延迟加载的提示...

感谢您的一些提示。

编辑:更正一些语法。

4

1 回答 1

0

对不起,缺少信息:

Mojarra JSF 实施 2.3.0 (20170310-1214)

素面 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; }

}

下一个懒人视图:

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;
    }
}

下一个惰性数据模型:

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;
    }
}

这是相同的行为:在加载滚动到开头之后,给定的 crate 是 150 个移位的 crate,而不是 crate[0]。希望有人可以验证这种行为。

于 2018-12-14T11:04:28.820 回答