GWT CellTable不必要地重建行

时间:2015-09-21 17:13:14

标签: gwt datagrid celltable gwt-celltable

我发现了一个有趣的问题,我想知道我是在滥用还是忽略了什么。我有一个可垂直滚动的大型CellTable。我想一次显示所有行而不是传统的分页。因此,在我的表格的底部,我有一行,用户可以单击以加载50行。我为表提供了一个自定义表构建器(setTableBuilder(new Builder());)。当用户点击“加载更多”时,我查询数据,添加到ListDataProvider并调用table.setVisibleRange(0,dataProvider.getList()。size());.

我在

中放了一个日志声明
@Override
public void buildRowImpl(Object rowValue, int absRowIndex) {
}

查看构建行的方法。我注意到它将构建0-dataProvider.getList()。size()(所有行),然后它将构建oldLength-dataProvider.getList()。size()(新行)。例如,如果我有100行然后加载50行,它将构建0-150,然后重建100-50。我想要的是它显然只构建新行。

所以我开始调试,看看为什么每次重建整个表。我发现在com.google.gwt.user.cellview.client.HasDataPresenter中它会在第1325行将“redrawRequired”标志设置为true:

else if (range1 == null && range0 != null && range0.getStart() == pageStart
    && (replaceDiff >= oldRowDataCount || replaceDiff > oldPageSize)) {
  // Redraw if the new data completely overlaps the old data.
  redrawRequired = true;
}

所以我的问题是为什么它认为新数据与旧数据完全重叠?

我是否使用了错误的东西,有更好的方法吗?当必须重新绘制数千行不需要重绘的行时,这会变慢。

谢谢, 将

2 个答案:

答案 0 :(得分:1)

我认为,在这种情况下,CellTablesetVisibleRange()方法调用的唯一反应是重绘所有行。

您刚刚通知CellTable现在必须显示新范围(0-150行)而不是最后一个(0-100行)。没有信息表明0-100行保持不变,并且不需要重绘它们。

有趣的是,您发现新行已更新(重建)两次:

  

例如,如果我有100行然后加载50行,那么它将构建0-150,然后重建100-50

我试图在最小的例子中重现这种行为:

public class ListDataProviderTest implements EntryPoint {

    private static final int ADD_COUNT = 10;

    private int nextVal = 0;

    public void onModuleLoad() {
        final CellTable<Integer> cellTable = new CellTable<Integer>();
        cellTable.addColumn(new TextColumn<Integer>() {
            @Override
            public String getValue(Integer object) {
                return object.toString();
            }});

        final ListDataProvider<Integer> listDataProvider = new ListDataProvider<Integer>();

        listDataProvider.addDataDisplay(cellTable);

        RootPanel.get().add(cellTable);
        RootPanel.get().add(new Button("Add more...", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                List<Integer> list = listDataProvider.getList();
                for(int i = 0; i < ADD_COUNT; i++)
                    list.add(nextVal++);
                cellTable.setVisibleRange(0, list.size());
            }
        }));
    }
}

但我将所有行更新一次。

您能否确认此示例重现问题或提供更准确的问题?

答案 1 :(得分:0)

AFAIK一个CellTable总是重绘所有细胞。 这就是CellTable的渲染器的工作原理。虽然它总是重绘所有单元格,但它在大多数情况下仍然比使用FlexTable更快,只更新几个单元格。