Skip to content
Ralph Schaer edited this page Apr 14, 2020 · 13 revisions

Server

ExtDirectSpring supports different kind of read requests from a DirectStore. Requests that support filtering, sorting and/or paging and requests that don't need all of these features.

A method that handles a simple read request from a DirectStore looks like this

      @ExtDirectMethod(ExtDirectMethodType.STORE_READ)
      public List<Person> loadAllPersons() {
         ...
      }

A simple read method is annotated with @ExtDirectMethod(ExtDirectMethodType.STORE_READ) and returns a collection of any object (may also return null).

To support filtering, sorting and/or paging the method needs an additional parameter of type ExtDirectStoreReadRequest that contains all the necessary informations. For this parameter the name does not matter.

      @ExtDirectMethod(ExtDirectMethodType.STORE_READ)
      public List<Person> loadAllPersons(ExtDirectStoreReadRequest request) {
        ...
      }

If the client needs to support paging the method has to return an instance of the class ExtDirectStoreResult. This class wraps the collection and the total number of available rows.

      @ExtDirectMethod(ExtDirectMethodType.STORE_READ)
      public ExtDirectStoreResult<Person> loadAllPersons(ExtDirectStoreReadRequest request) {
        ...
        return new ExtDirectStoreResult<Person>(totalSize, persons);
      }

ExtDirectStoreReadRequest contains these properties

query String This property is used for combo boxes where queryMode is 'remote'. If the user types something into the combo box, requests are sent to the server and this property contains the user input.
limit Integer If the control on the client side uses paging this parameter specifies the number of records the server should send back in one request
start Integer In a paging request this specifies the starting index. The program has to send the data rows from *start* until *start+limit-1* back
page Integer In a paging request specifies the requested page. Ext JS 3.0 only sends limit and start, Ext JS 4.x additionally sends *page*.
sort String Name of the field to sort the list
dir String Sort direction. "ASC" for ascending and "DESC" for descending
groupBy String Name of the field to group the list
groupDir String Sort direction of the group field. "ASC" for ascending and "DESC" for descending
sorters List SortInfo Ext JS 4.x supports more than one sorter for a grid. This collection contains all the specified sort informations.
groups List GroupInfo Ext JS 4.x supports more than one group for a grid. This collection contains all the specifed group informations.
filters List Filter List of Grid Filters
params Map Contains all the parameters the client specified in the extraParams property

The properties are null if there is no data, except the collection properties (sorters, groups, filters) which are set to an empty list.

To create an instance of ExtDirectStoreResult call one of the available constructors.

  //Use this constructor if there is no paging involved
  return new ExtDirectStoreResult(aCollection);

  //If the client splits the data into different pages, he has to know 
  //the total number of available records. The first constructor argument 
  //provides this information
  return new ExtDirectStoreResult(totalNoOfRows, aCollection);

  //If you have to set the success flag to false use this constructor. 
  //The first two constructors set the success flag to true.
  return new ExtDirectStoreResult(totalNoOfRows, aCollection, false);

Grid Filters

The filters property of ExtDirectStoreReadRequest is a list of Filters. There are 5 implementation of the Filter interface.

The field property specifies the name of the field to filter on. The filter value is stored in the value property. DateFilter and NumericFilter contain an additional property (comparison) that specifies if the value is less than, greater than or equal.

Client Ext JS 3.x

A DirectStore without paging can be build like this.

      var simpleStore = new Ext.data.DirectStore( {
        paramsAsHash: true,
        root: 'records',
        directFn: personAction.loadAllPersons,
        fields: ['id', 'firstName', 'lastName']
      });

The property paramsAsHash must be set to true. root property is always 'records'. directFn specifies the server method to call for reading the data. fields must correspond with the field names of the Java bean from the server.

Another useful property is autoLoad. DirectStore loads the data automatically after the creation of the DirectStore. If you want to start the load process manually set autoLoad to false and call simpleStore.load().

Don't set the restful property to true. ExtDirect does not work with restful DirectStores.

A store with paging support

      var directStoreWithPaging = new Ext.data.DirectStore( {
        id: 'myStore',
        paramsAsHash: true,
        root: 'records',
        totalProperty: 'total',
        remoteSort: true,
        directFn: personAction.loadAllPersons,
        fields: ['id', 'firstName', 'lastName']
      });

There is an additional property totalProperty which specifies the name of a field in the response that provides the total number of available rows. The name of this property corresponds with the names of the property in the class ExtDirectStoreResult. If the sort should happen on the server set the remoteSort property to true (defaults to false).

If you want initially load data into a paging GridPanel don't set the autoLoad property of the DirectStore to true. If this property is true the store will load all data immediately. Instead omit the property or set it to false and manually call the load method with the desired start and limit parameters. This is only necessary for the first call, subsequent calls will be handled by the paging GridPanel.

      Ext.StoreMgr.get('myStore').load( {
        params: {
          start: 0,
          limit: 20
        }
      });

Client Ext JS 4.x and Sencha Touch 2.x

A DirectStore can be created like this. The configuration usually consists of a Model and a Store object. It's possible to omit the Model object and put everything into the Store configuration.

    Ext.define('MyModel', {
      extend: 'Ext.data.Model',
      fields: [ 'id', 'firstName', 'lastName' ]
    });
    
    var store = Ext.create('Ext.data.Store', {
      model: 'MyModel',
      proxy: {
        type: 'direct',
        directFn: personAction.loadAllPersons
      }
    });
    
    //OR move the proxy definition into the Model
    
    Ext.define('MyModel', {
      extend: 'Ext.data.Model',
      fields: [ 'id', 'firstName', 'lastName' ],
      proxy : {
        type: 'direct',
        directFn: personAction.loadAllPersons
      }  
    });
    
    var store = Ext.create('Ext.data.Store', {
      model: 'MyModel'
    });
    
    //OR all in one Store config
    
    var store = Ext.create('Ext.data.Store', {
      model: 'MyModel',
      fields: [ 'id', 'firstName', 'lastName' ],
      proxy: {
        type: 'direct',
        directFn: personAction.loadAllPersons
      }
    });

My preferred solution is putting the proxy configuration into the model. This way it's possible to use the model class independently of a store and methods like save() and destroy() are working.

A store supports auto loading and remote sorting. The following configuration will load the data immediately after creation. Sorting will happen on the server and the data is initially sorted by lastName and firstName.

    var store = Ext.create('Ext.data.Store', {
      model: 'MyModel',
      autoLoad: true,
      remoteSort: true,
      sorters: [ {
        property: 'lastName',
        direction: 'ASC'
      }, {
        property: 'firstName',
        direction: 'DESC'
      } ]
    });

Be aware that even the above examples do not specify any paging the client sends paging information. The default values are page=1, start=0 and limit=25 and the ExtDirectStoreReadRequest object contains this values. If paging is not supported the server method can simply ignore these values.

The default paging size of 25 can be overridden with pageSize. The following configuration sets the size to 50 rows.

    var store = Ext.create('Ext.data.Store', {
    	model: 'MyModel',
    	pageSize: 50,
    	remoteSort: true,
    	autoLoad: true
    });

To support paging it's mandatory to specify the root property of the proxy reader. With ExtDirectSpring this is always reader: { root: 'records'} and the server method has to return a ExtDirectStoreResult instance.

    Ext.define('MyModel', {
      extend: 'Ext.data.Model',
      fields: [ 'id', 'firstName', 'lastName' ],
      proxy : {
        type: 'direct',
        directFn: personAction.loadAllPersons,
        reader: {
          root: 'records'
        }
      }  
    });

It's possibly to always specify reader: { root: 'records'} even when the server method returns a simple collection and not a ExtDirectStoreResult. Ext JS is able to handle both responses. This way the same model can be used in a paging and a non-paging grid.

Infinite scrolling is a new feature in Ext JS 4.x and is also supported. It only needs an additional property buffered: true in the store configuration.

    var store = Ext.create('Ext.data.Store', {
      pageSize: 200,
      autoLoad: true,
      model: 'MyModel',
      remoteSort: true,
      buffered: true

Because infinite scrolling loads the data in pages the server method needs to support paging and returns ExtDirectStoreResult. Also the root property of the proxy reader has to be 'records'.

Clone this wiki locally