06 February 2008

Ext JS - One Service Several Stores

One Service - One Store
The ExtJS framework makes loading data from an ASP.Net XML Service a snap. The pattern for retrieving data from the server is as follows:
  • Create a service (server side)
  • Define a record structure
  • Define a record reader
  • Define a server proxy (Http) to deliver data to the reader
  • Define a data store and load the data
Create the web service that serves up your data. Since I am using ASP.Net, the service returns a dataset as an XMLDocument. But the data can also be served back as JSON or put directly onto the page.

Create a Ext.Record definition for parsing the data. An example is listed below. The record is going to be displayed in a combo box.

// record object definition
var xmlRec = new xd.Record.create([
{name: 'entid', type: 'string'},
{name: 'entnm', type: 'string'}
]);


Create an Ext.Reader object. Ext JS provides XML and JSON readers. A sample XmlReader is listed below.

// xml reader for the entity dropdown
var xmlReader = new xd.XmlReader(
{
record: 'entity',
id: 'entid'
},
xmlRec
);


Create an Ext.HttpProxy object. For ASP.Net I have found that the URL and method attributes both have to be initialized.

Inside tip: When using ASP.Net 2.0 you will have to enable POST on your IIS server via the web.config or this won't work. See this Microsoft KB on how to enable POST on IIS.

// proxy for the entity connection
var proxyEntity = new xd.HttpProxy({
url: 'services.asmx/combInit',
method: 'POST'
});


Create an Ext.Store object for delivery to your consumer.
// create the store
var str = new xd.Store({
proxy: proxyEntity,
reader: xmlReader
});


One Service - Multiple Stores
.Net makes it easy to share connections using ADO.Net and then persist the data in a DataSet on the server for delivery to the client. Imagine if you could load all the 'static' data fields on your page from one service in one call. If you look at the abstraction pattern outlined above, the answer is not obvious - but Ext JS makes it easy.

The pattern for using one service for deliver to several stores is only slightly different.
  • Register a function on the 'load' event for the first store. This function will load the data into the other stores.
  • Deliver data to the first store as above. Make sure to invoke the load() method.
  • Create your new record and reader definitions.
  • Retain a variable that points to the original data. The example here is for XML.
  • Use a Memory Proxy to load the existing data into a new store(s).
Registration for events is relatively simple. In the example below, I create a new combo object and pass the XMLData into the constructor of the object. This xmlData contains all the data for all the combos on my form.

store.on('load',function(t, rec, opt){
var sct1Cb = new Sector1Combo(entCb.xmlReader.xmlData);
....(load other data)
});


Creating the record definition and XMLReader object was covered above so I will skip it here. The important thing is to replace the HttpProxy with a MemoryProxy, using the XML data in the constructor.
var str = new xd.Store({
proxy: new Ext.data.MemoryProxy(XmlDocument),
reader: xmlReader
});
str.load();


Using this second technique, you only have to make one web service to load your combo boxes. On the server side, that means you only have to connect one time to the database for your static data. It also cuts down considerably on the code you have to write and maintain.