GWT 使用 RequestFactory 将 Objectify Cursor 从服务器传递到客户端,并在 DataG



我是游标的新手,有以下方法:

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 接口,并打算将一个包含 Cursor 的列表传回给客户端 - 唯一的问题是 RequestFactory 只能处理从服务器到客户端的某些类型的传递 - 这个自定义类型不是其中之一。 那么,现在使用GWT RequestFactory - 有没有一种好方法可以将Objectify光标从服务器传递到客户端?

另外 - 我遇到的另一个问题 - 如果我用这些数据填充 DataGrid,它会在网格中显示数据 - 但仅此而已 - 寻呼机显示 1-25 中的 25。 所以,我想知道的是,你如何实际告诉DataGrid服务器上有更多的可用数据。 我有点困惑,因为似乎没有很多文档/示例可用于此。

谢谢


对于遇到此问题的其他任何人,我找到了其中一部分的答案 - 我忘记了所有关于 ValueProxies 的信息,它允许您使用 RequestFactory 映射标准 java bean 以从服务器返回到客户端。

不幸的是,您不能将泛型与 ValueProxy 一起使用,因此我必须为每个单独的类型创建一个 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);
}

所以 - 这就是它的一部分 - 我还没有完全弄清楚如何做的一件事是正确设置寻呼机 - 我想显示寻呼机中的项目总数以允许您翻页,但我不确定具体如何做到这一点 - 如果我找到解决方案,我会发布它

您可以将Cursor转换为可序列化的字符串 - 实际上您已经使用了这个:iterator.getCursor().toWebSafeString() .

只需将序列化游标(= a String)与所有其他列表数据一起返回给客户端,并在下一个请求中将其作为参数提供。

Optonaly 在片段标识符(又名 GWT 历史令牌)中使用它,以便用户实际上可以为列表中的特定页面添加书签(取决于用例,如果列表数据变化不大,则有意义)。

最新更新