One of the things I <3 about Sencha is the data store.  They are super-simple to create, but very powerful for creating robust, data-driven applications.  The other day, I found myself creating 3 data stores that were extremely similar, simply because of the fact that the data returned was fairly complex and nested.  You see, with a Sencha store, you define a “root” of your data, which is really just how the store’s Reader will treat the “rows” of data that are fed into the store.  This works very well, but in my scenario, I was wanting to create a master store of data defined at the highest possible root, and then create child stores based on some of the nested objects belonging to my initial data set.  So in this case, instead of making 3 remote calls to get the same, but differently-structured data, I wanted to make 1 request and use the result 2 more times for different stores.

At first, I looked to the store itself for something like a “copy” or “clone” method, but there was none.  There IS an option for doing an “each” loop for every record, but that just seemed a bit overkill.  But then I took a step back and thought about a store’s data.  When you get down to it, loading data into a store is not a magic process, nor is the format some mystical, obfuscated structure.  The data is really only an object, and correlates precisely to what you define for the Store’s reader.

With this knowledge in hand, I tried the following:

var artiststore = new Ext.data.JsonStore({
     storeId: "artiststore",
     url:     "handler.cfm",
     baseParams: {method:"artistdetails",artistId:11525145},
     root:    "artist",
     fields:  extartistfields.getRange(),
     listeners: {
           load:function(el,records){
                artisttrackstore.loadData(records[0].json);
                artistalbumstore.loadData(records[0].json);
           }
     }
});


var artisttrackstore = new Ext.data.JsonStore({
storeId:"artisttrackstore",
root: "topTrack",
fields: trackfields.getRange()
}); var artistalbumstore = new Ext.data.JsonStore({ storeId:"artistalbumstore", root: "topAlbums", fields: albumfields.getRange() });

… and it worked brilliantly.

Nothing tremendously crazy happening here.  First, I create a listener on my “parent” store for the “load” method (this fires AFTER data has been loaded into the store).  Then, on the load method, I simply initiate a loadData() on each of my child stores, passing to them the object expected by their internal Reader (in this case, a json-formatted string).  Then, to wrap things up, I simply define a new “root” on each child store, each corresponding to the nested object from the parent store that I wanted to drill down into.

Nice! 🙂