我对于整理一个CellTable非常感兴趣。我也去了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类中调用一个方法,该方法包含一个地图和一个列表。在进行rpc调用之前,将检查缓存是否已经采用然后显示的事件。
getEvents只是通过asynccallback进行rpc调用,成功时通过updateRowData()更新rowdata。
我的表格快速显示,目前约有500个条目(可能更多,取决于客户)。没有丢失的数据和分页工作正常。
我无法进行分类工作。据我所知,AsyncHandler将触发setVisibleRangeAndClearData(),然后触发onRangeChanged()。 onRangeChanged永远不会被解雇。至于setVisibleRangeAndClearData(),我不知道。但是sortindicator(列名旁边的箭头)确实会在每次点击时发生变化。
我不想让服务器对列表进行排序。我有自己的比较器。如果对表的当前可见页面进行排序就足够了。我现在想要对整个列表进行排序。
我在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来确定列的名称。否则,我应该怎么知道,哪个列被点击了?页面现在排序,但我必须在列上单击两次。之后,每次点击都会完成排序,但顺序错误。
这个解决方案确实需要抛光,对我来说似乎有点不好看。有更好的想法吗?
答案 0 :(得分:1)
您链接到的教程声明:
这个排序代码在这里,所以示例有效。在实践中,你会的 在服务器上排序。
异步提供程序用于显示太大而无法在单个调用中加载的数据。当用户单击任何列进行排序时,客户端上没有足够的对象来显示“按名称排序的前20个evens”或应用的任何排序。您必须返回到您的服务器并请求按名称按升序排序的前20个事件。当用户撤消排序时,您必须再次转到服务器以按降序排序按名称排序的前20个事件等。
如果您可以在一次调用中加载所有数据,那么您可以使用常规DataProvider,并且所有排序都可以在客户端进行。
编辑:
发布代码中的问题出现在EventsDataProvider的构造函数中。现在它调用onRangeChanged,应用程序可以从服务器加载新的事件排序列表。