Я новичок в курсорах и использую следующий метод:
public List<Venue> findPage(Subject subject, Objectify ofy, int pageSize) {
final Business business = (Business) subject.getSession().getAttribute(BUSINESS_ATTRIBUTE);
final Query<Venue> query = ofy.query(Venue.class).filter(BUSINESS_ATTRIBUTE, business);
final String encodedCursor = (String) subject.getSession().getAttribute(VENUE_CURSOR_CONDITION);
if (encodedCursor != null) {
query.startCursor(Cursor.fromWebSafeString(encodedCursor));
}
final QueryResultIterator<Key<Venue>> iterator = query.fetchKeys().iterator();
final List<Key<Venue>> data = new ArrayList<Key<Venue>>(pageSize);
boolean more = false;
for (int i = 0; i < pageSize && (more = iterator.hasNext()); i++) {
data.add(iterator.next());
}
subject.getSession().setAttribute(VENUE_CURSOR_CONDITION, iterator.getCursor().toWebSafeString());
return get(ofy, data);
}
где get - это следующий метод
public <T> List<T> get(Objectify ofy, List<Key<T>> keys) {
if (keys == null) {
return null;
}
final Map<Key<T>, T> map = ofy.get(keys);
final List<T> list = new ArrayList<T>();
for (T t : map.values()) {
list.add(t);
}
return list;
}
Теперь, вот что я делаю сейчас - это немного хакерски. Я использую Apache Shiro для отслеживания сеансов пользователя - в сеансе пользователя я сохраняю последний использованный курсор - если пользователь уходит со страницы, я устанавливаю для курсора значение false (очевидно - это очень, очень хрупко, поскольку требует каждый метод иметь код для аннулирования последнего курсора).
Теперь, вот где меня ловят. Я сделал простой интерфейс HasCursor и собирался передать список с курсором на стороне клиента - единственная проблема заключается в том, что RequestFactory может обрабатывать передачу только определенных типов с сервера на клиент - этот пользовательский тип не является одним из них. Итак, прямо сейчас с GWT RequestFactory — есть ли хороший способ передать курсор Objectify с сервера на клиент?
Кроме того - еще одна проблема, с которой я сталкиваюсь - если я заполняю DataGrid этими данными, он показывает данные в сетке в порядке - но это все - пейджер говорит 1-25 из 25. Итак, мне интересно, как вы на самом деле сообщаете DataGrid, что на сервере доступно больше данных. Я немного смущен, так как кажется, что для этого не так много документации/примеров.
Большое Вам спасибо
для всех, кто сталкивается с этой проблемой, я нашел ответ на одну ее часть - я забыл все о ValueProxies, которые позволяют вам отображать стандартные java-бины для возврата на клиентскую сторону с сервера с помощью RequestFactory.
К сожалению, вы не можете использовать Generics с ValueProxies, поэтому мне пришлось создать оболочку ListCursor для каждого отдельного типа.
Вот прокси:
@ProxyFor(value = VenueListCursorWrapper.class)
public interface VenueListCursorWrapperProxy extends ValueProxy {
List<VenueProxy> getVenues();
String getCursor();
boolean isMoreAvailable();
void setVenues(List<VenueProxy> venues);
void setCursor(String cursor);
void setMoreAvailable(boolean moreAvailable);
}
и вот обновленный метод на сервере:
public VenueListCursorWrapper findPage(Subject subject, Objectify ofy, int pageSize, String cursor) {
final Business business = (Business) subject.getSession().getAttribute(BUSINESS_ATTRIBUTE);
final Query<Venue> query = ofy.query(Venue.class).filter(BUSINESS_ATTRIBUTE, business);
if (cursor != null) {
query.startCursor(Cursor.fromWebSafeString(cursor));
}
final QueryResultIterator<Key<Venue>> iterator = query.fetchKeys().iterator();
final List<Key<Venue>> data = new ArrayList<Key<Venue>>(pageSize);
boolean more = false;
for (int i = 0; i < pageSize && (more = iterator.hasNext()); i++) {
data.add(iterator.next());
}
return new VenueListCursorWrapper(get(ofy, data), iterator.getCursor().toWebSafeString(), more);
}
Итак - это та часть - единственное, что я до сих пор не совсем понял, как правильно настроить пейджер - я хотел бы показать общее количество элементов в пейджере, чтобы вы могли просматривать его. но я пока не уверен, как именно это сделать - если я найду решение, я опубликую его