Gwt Простые проблемы с пейджером в обработчике сортировки столбцов
Я настроил AsyncDataProvider для моего CellTable и добавил его в SimplePager. Я подключил ListHandler, чтобы позаботиться о сортировке по столбцу. Когда я щелкаю по заголовку этого столбца, данные не меняются, но при переходе на следующую / предыдущую страницу в пейджере данные сортируются. Кроме того, до щелчка по столбцу в столбце отсутствует визуальный индикатор, который бы указывал, что он предназначен для сортировки.
Как я могу получить данные для обновления, когда я нажимаю на заголовок столбца?
Вот мой фрагмент кода
service.getHosts(environment, new AsyncCallback<Set<String>>() {
@Override
public void onSuccess(final Set<String> hosts) {
final List<String> hostList = new ArrayList<String>(hosts);
//Populate the table
CellTable<String> hostTable = new CellTable<String>();
TextColumn<String> hostNameColumn = new TextColumn<String>(){
@Override
public String getValue(String string){
return string;
}
};
NumberCell numberCell = new NumberCell();
Column<String, Number> lengthColumn = new Column<String, Number>(numberCell){
@Override
public Number getValue(String string) {
return new Integer(string.length());
}
};
AsyncDataProvider<String> dataProvider = new AsyncDataProvider<String>() {
@Override
protected void onRangeChanged(HasData<String> data) {
int start = data.getVisibleRange().getStart();
int end = start + data.getVisibleRange().getLength();
List<String> subList = hostList.subList(start, end);
updateRowData(start, subList);
}
};
// Hooking up sorting
ListHandler<String> columnSortHandler = new ListHandler<String>(hostList);
columnSortHandler.setComparator(lengthColumn, new Comparator<String>(){
@Override
public int compare(String arg0, String arg1) {
return new Integer(arg0.length()).compareTo(arg1.length());
}
});
hostTable.setPageSize(10);
hostTable.addColumnSortHandler(columnSortHandler);
hostTable.addColumn(hostNameColumn,"Host Name");
lengthColumn.setSortable(true);
hostTable.addColumn(lengthColumn, "Length");
VerticalPanel verticalPanel = new VerticalPanel();
SimplePager pager = new SimplePager();
pager.setDisplay(hostTable);
dataProvider.addDataDisplay(hostTable);
dataProvider.updateRowCount(hosts.size(), true);
verticalPanel.add(hostTable);
verticalPanel.add(pager);
RootPanel.get().add(verticalPanel);
}
@Override
public void onFailure(Throwable throwable) {
Window.alert(throwable.getMessage());
}
});
Я не уверен, как сделать так, чтобы список использовался как таблицей, так и пейджером. Перед добавлением пейджера я использовал
ListDataProvider<String> dataProvider = new ListDataProvider<String>();
ListHandler<String> columnSortHandler = new ListHandler<String>(dataProvider.getList());
AsyncDataProvider не имеет метода getList
,
Подводя итог, я хочу, чтобы данные сортировались сразу после щелчка по столбцу, а не после того, как я переместился вперед / назад с помощью элементов управления пейджером.
В соответствии с предложением я изменил код для AsyncDataProvider на
AsyncDataProvider<String> dataProvider = new AsyncDataProvider<String>() {
@Override
protected void onRangeChanged(HasData<String> data) {
int start = data.getVisibleRange().getStart();
int end = start + data.getVisibleRange().getLength();
List<String> subList = hostList.subList(start, end);
// Hooking up sorting
ListHandler<String> columnSortHandler = new ListHandler<String>(hostList);
hostTable.addColumnSortHandler(columnSortHandler);
columnSortHandler.setComparator(lengthColumn, new Comparator<String>(){
@Override
public int compare(String v0, String v1) {
return new Integer(v0.length).compareTo(v1.length);
}
});
updateRowData(start, subList);
}
};
Но нет никаких изменений в поведении даже после этого. Может кто-нибудь, пожалуйста, объясните процесс. Похоже, что в демонстрационном приложении GWT есть эта функциональность, но не совсем ясно, как они это сделали.
2 ответа
При использовании AsyncDataProvider разбиение на страницы и сортировка должны выполняться на стороне сервера. Вам понадобится AsyncHandler для работы с AsyncDataProvider:
AsyncHandler columnSortHandler = new AsyncHandler(dataGrid) {
@Override
public void onColumnSort(ColumnSortEvent event) {
@SuppressWarnings("unchecked")
int sortIndex = dataGrid.getColumnIndex((Column<Entry, ?>) event.getColumn());
boolean isAscending = event.isSortAscending();
service.getPage(0, sortIndex, isAscending, new AsyncCallback<List<Entry>>() {
public void onFailure(Throwable caught) {
}
public void onSuccess(List<Entry> result) {
pager.setPage(0);
provider.updateRowData(0, result);
}
});
}
};
dataGrid.addColumnSortHandler(columnSortHandler);
Нажатие на заголовок столбца вызовет columnSortEvent. Затем вы должны нажать на столбец. Я перегружаю свой сервлет, чтобы обеспечить сортировку и разбиение на страницы, поэтому я передаю -1 для индекса столбца, когда требуется только разбиение на страницы.
provider = new AsyncDataProvider<Entry>() {
@Override
protected void onRangeChanged(HasData<Entry> display) {
final int start = display.getVisibleRange().getStart();
service.getPage(start, -1, true, new AsyncCallback<List<Entry>>() {
@Override
public void onFailure(Throwable caught) {
}
@Override
public void onSuccess(List<Entry> result) {
provider.updateRowData(start, result);
}
});
}
};
provider.addDataDisplay(dataGrid);
provider.updateRowCount(0, true);
Затем ваша реализация сервлета getPage выполняет сортировку и разбиение на страницы. За всем этим гораздо проще следить с помощью отдельных обработчиков событий.
Я думаю, что проблема с инициализацией ListHandler. Вы передаете hostList в качестве параметра в обработчик списка, а в методе onRangeChange вы вызываете updateRowData с другим списком (подсписком).
Make sure you use the same list in both the places
,
или же
Move your ListHander initialization and cellTable.addColumnSortHandler method call to onRangeChange method after updateRowData call.