Straightforward example for loading data into a Sencha GXT (3.0) ListStore using a GWT RPC call?

Bionic_Geek picture Bionic_Geek · May 13, 2012 · Viewed 9.4k times · Source

Does anyone have or know of an example which demonstrates loading data via a GWT RPC call into a ListStore using Sencha GXT 3.0? I know there are numerous examples of using the ModelData and BeanModel interfaces used in the 2.x versions but 3.0 does away with the need to use these interfaces and supposedly allows for POJO objects to be loaded in using classes which implement the ValueProperty interface.

I have seen the RequestFactoryBinding example and the RequestFactory Grid example in the 3.0 Explorer but those appear to demonstrate the use of a custom Data Proxy and a Receiver. I assume from reviewing the code in those examples that these techniques/classes may be required but that is not made apparent anywhere. It's possible that there is more documentation forthcoming but so far I haven't been able to find much of anything beyond that javadocs and the Explorer which lacks some of the source classes used in the example methods.

Links to both examples below.

The RequestFactoryBinding Example: http://www.sencha.com/examples/#ExamplePlace:requestfactorybinding

RequestFactory Grid example: http://www.sencha.com/examples/#ExamplePlace:requestfactorygrid

Answer

Colin Alworth picture Colin Alworth · May 14, 2012

DataProxy and Loader are used mostly to facilitate a) relying on the server for filtering/paging/sorting, or b) reuse between parts of the application for getting access to the same pieces of data. They are not required (as in 2.x) in cases where the client only loads data once, or where manual store management is done.

The various store loading classes (ListStoreBinding, LoadResultListStoreBinding) demonstrate internally how the ListStore can be fed items. This first way allows you to replace the existing items in the store from the onSuccess method in your RPC callback or RequestFactory receiver:

List<MyData> newItems = ...;//response from server
ListStore<MyData> store = ...;//current store to replace/update
store.replaceAll(newItems);

If only loading once, or only appending, not replacing, the other method should be used:

store.addAll(newItems);

Items can be added one by one using store.add, however this will result in an event per item, and should be avoided.

Edit: Also, and this may not totally be clear coming from 2.x, but no superclass/interface is required for data itself. ValueProvider is only used as an external abstraction for how models are manipulated - how values are generically read or set from any kind of model. The PropertyAccess interface allows ValueProvider (and other) instances to be generated by just the property name that the values will be get/set from using bean accessors. ValueProvider types/instances are not required for loading data, merely for the data widgets themselves to extract the data they are displaying, and to make modifications after the user edits the values.


Knowing these pieces, the loader/proxy mechanism will be loading data in the same basic way. The Loader is responsible for being told what settings (paging, filtering, and/or sorting) to use when loading, then triggering the load - different subclasses have different responsibilities, accept different load config types, and return different results. The DataProxy then is the mechanism that actually talks to whatever holds the data, asynchronously if on a server, and informs the loader when the results are available via a callback.

The examples listed in the question both use RequestFactory, but there are several examples as well that use RPC, and a few loading from just JSON or XML. In http://www.sencha.com/examples/#ExamplePlace:paginggrid the main data loading parts are as follows:

// The rpc async instance
final ExampleServiceAsync service = GWT.create(ExampleService.class);

// As in Ext GWT 2, there is a convenience proxy for RPC to just pass the callback 
// directly to the RPC call. If you need a custom callback, just be sure to invoke 
// `callback.onSuccess` with the final result.
RpcProxy<PagingLoadConfig, PagingLoadResult<Post>> proxy = new RpcProxy<PagingLoadConfig, PagingLoadResult<Post>>() {
  @Override
  public void load(PagingLoadConfig loadConfig, AsyncCallback<PagingLoadResult<Post>> callback) {
    service.getPosts(loadConfig, callback);
  }
};
// ...

// The loader itself has a reference to the proxy so that loader.load() results
// in a round trip to the server, as outlined above.
final PagingLoader<PagingLoadConfig, PagingLoadResult<Post>> loader = new PagingLoader<PagingLoadConfig, PagingLoadResult<Post>>(
    proxy);
loader.setRemoteSort(true);

// This last piece - instead of 2.x where the loader is a parameter to the store,
// in 3 you directly wire the results of the loader to add the items into the
// store, as discussed in the first half of this answer
loader.addLoadHandler(new LoadResultListStoreBinding<PagingLoadConfig, Post, PagingLoadResult<Post>>(store));