GWT pass Objectify Cursor from Server to Client with RequestFactory and show more pages in DataGrid

眉间皱痕 提交于 2019-12-11 11:41:59

问题


I am brand new to cursors and have the following method:

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);
}

where get is the following method

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;
}

Now, here's what I'm doing currently - which is a little hackish. I am using Apache Shiro to track User's sessions - in the user's session I am keeping the last cursor that was used - if the user navigates away from the page i set the cursor to false (obviously - this is very, very brittle as it requires every method to have a code to invalidate the last cursor).

Now, here's where I'm getting caught. I made a simple HasCursor interface, and was going to pass back a List with Cursor in it to the client side - the only problem is RequestFactory can only handle passing certain types from server to client - this Custom type isn't one of them. So, right now with GWT RequestFactory - is there a good way to pass an Objectify Cursor from the Server to the Client?

Also - another issue I'm running into - if I populate the DataGrid with this data it shows the data fine in the grid - but that's it - the pager says 1-25 out of 25. So, what I'm wondering is, how do you actually tell the DataGrid that there is more data available on the server. I'm a little confused as it seems there isn't a whole lot of documentation / examples available for this.

Thank you very much


for anybody else that runs into this problem i found out the answer to one part of it - i forgot all about ValueProxies that allow you to map standard java beans to return to the client side from the server with RequestFactory.

Unfortunately, you can't use Generics with ValueProxies so I had to create a ListCursor wrapper for each individual type.

Here's the proxy:

@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);
}

and here's the updated method on the server:

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);
}

So - that's that part of it - the one thing I still haven't quite figured out how to do is get the pager set up correctly - I would like to show the total count of items in the pager to allow you to page through it but I'm not sure exactly how to do this yet - if I find a solution I will post it


回答1:


You can convert Cursor to a serializable string - actually you already use this: iterator.getCursor().toWebSafeString().

Just return the serialized cursor (= a String) to the client together with all other list data and on the next request provide it as a parameter.

Optonaly use it in fragment identifier, aka GWT history token, so that user can actually bookmark the particular page in your list (depends on the use case, makes sense if list data does not change much).



来源:https://stackoverflow.com/questions/11058737/gwt-pass-objectify-cursor-from-server-to-client-with-requestfactory-and-show-mor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!