我的 CellTable 不排序

My CellTable does not sort

我对单元格排序很感兴趣Table。我也经历了 ColumnSorting with AsyncDataProvider。但是我的CellTable没有排序。

这是我的代码:

public class EventTable extends CellTable<Event> {

public EventTable() {

  EventsDataProvider  dataProvider = new EventsDataProvider(this);
  dataProvider.addDataDisplay(this);

  SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
  SimplePager pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 5, true);
  pager.setDisplay(this);

  [...]
  TextColumn<Event> nameCol = new TextColumn<Event>() {
  
    @Override
    public String getValue(Event event) {
  
      return event.getName();
    }
  };

  nameCol.setSortable(true);

  AsyncHandler columnSortHandler = new AsyncHandler(this);
  addColumnSortHandler(columnSortHandler);

  addColumn(nameCol, "Name");

  getColumnSortList().push(endCol);

  }

}


public class EventsDataProvider extends AsyncDataProvider<Event> {

  private final EventTable eventTable;

  public EventsDataProvider(EventTable eventTable) {
  
    this.eventTable = eventTable;
  }

  @Override
  protected void onRangeChanged(HasData<Event> display) {

    int start = display.getVisibleRange().getStart();
    int length = display.getVisibleRange().getLength();

    // check false values
    if (start < 0 || length < 0) return;

    // check Cache before making a rpc
    if (pageCached(start, length)) return;

    // get Events async
    getEvents(start, length);
  }
}

我现在知道了,如果这里需要所有的方法。如果是这样,我会添加它们。但简而言之:

pageCached 调用我的 PageCache Class 中的一个方法,它包含一个地图和一个列表。在进行 rpc 调用之前,将检查缓存是否已经获取并显示事件。

getEvents 只是通过 asynccallback 进行 rpc 调用,成功时通过 updateRowData() 更新行数据。

我的 Table 显示速度很快,目前大约有 500 个条目(可能更多,取决于客户)。没有丢失数据,分页工作正常。

我无法完成分类工作。据我所知,AsyncHandler 将触发 setVisibleRangeAndClearData(),然后触发 onRangeChanged()。 onRangeChanged 永远不会被解雇。至于 setVisibleRangeAndClearData() 我不知道。但是排序指示器(列名旁边的箭头)确实会在每次点击时发生变化。

我不想让服务器对列表进行排序。我有自己的比较器。如果 table 的当前可见页面已排序,就足够了。我现在想对整个列表进行排序。

编辑:

我在 EventTable 构造函数中更改了以下代码:

public EventTable() {
  [...]
  addColumnSortHandler(new ColumnSortEvent.AsyncHandler(this) {
  
    public void onColumnSort(ColumnSortEvent event) {
  
      super.onColumnSort(event);
      MyTextColumn<Event> myTextColumn;
    
      if (event.getColumn() instanceof MyTextColumn) {
        // Compiler Warning here: Safetytype unchecked cast
        myTextColumn = (MyTextColumn<Event>) event.getColumn();
        MyLogger.log(this.getClass().getName(), "asc " + event.isSortAscending() + " " + myTextColumn.getName(), Level.INFO);
      }
    
      List<Event> list = dataProvider.getCurrentEventList();
      if (list == null) return;
    
      if (event.isSortAscending()) Collections.sort(list, EventsComparator.getComparator(EventsComparator.NAME_SORT));
      else Collections.sort(list, EventsComparator.descending(EventsComparator.getComparator(EventsComparator.NAME_SORT)));
    }
  });
  
  addColumn(nameCol, "Name");

  getColumnSortList().push(endCol);
}

我不得不编写自己的 TextColumn 来确定列的名称。否则我怎么知道点击了哪一列?该页面现在已排序,但我必须在该列上单击两次。之后,每次点击都会进行排序,但顺序错误。

这个解决方案确实需要改进,我觉得它有点老套。有更好的想法吗?

您链接到的教程指出:

This sorting code is here so the example works. In practice, you would sort on the server.

异步提供程序用于显示太大而无法在单个调用中加载的数据。当用户单击任何列对其进行排序时,客户端根本没有足够的对象来显示 "first 20 evens by name" 或应用任何排序。您必须返回到您的服务器并请求按名称升序排序的前 20 个事件。而当用户反向排序时,你必须再次去服务器获取前 20 个事件按名称降序排列等

如果您可以在一次调用中加载所有数据,那么您可以使用常规 DataProvider,并且所有排序都可以在客户端进行。

编辑:

发布的代码中的问题出在 EventsDataProvider 的构造函数中。现在它调用 onRangeChanged,应用程序可以从服务器加载新的排序事件列表。