Ext JS Data Store Dependency Injection

A feature I really like in the Ext JS framework is that components that use extjs data stores do not necessarily need to be supplied actual references to the stores at configuration time.  These components can also be supplied a string key – the identifier of the store – that will be used to obtain the data store reference from an external repository.

Besides reducing lines of code, this dependency injection approach relieves us, to a great extent, of having to track what data store references we supply to what components.

Let’s see how the feature works by stepping through a hypothetical example.  Assume we have an “Employees”  extjs data store, defined with the code that follows:

EmployeesStore = Ext.extend(Ext.data.JsonStore, {
    storeId: "employeesStore",
    constructor: function() {
        EmployeesStore.superclass.constructor.call(this, {
            fields : [ // Fields ]
        });
    }
});

The StoreMgr class as a global registry of data stores

With the incorporation of the StoreMgr class, Ext JS provides a container that can be used as a global registry for the data stores we have created in our applications.  Although data stores can be added to this registry manually, they are automatically added by the framework if we use the storeId option in the store configuration, as we did above.

This makes it possible to configure an “Employees” grid panel with the store’s id, as shown in the following code:

EmployeedGrid = Ext.extend(Ext.grid.GridPanel, {
    title: "Employees List",
    store: "employeesStore",
    width: 400,
    height: 250,
    initComponent: function() {
        this.columns = [ // Columns ];
        EmployeedGridUi.superclass.initComponent.call(this);
    }
});

See the difference?  Where we could have used store:EmployeesStore, we used store:”employeesStore”, and made our grid responsible for obtaining the reference to the store whose id is “employeesStore”.

We can do this because the initComponent method of the GridPanel class contains the following call:

this.store = Ext.StoreMgr.lookup(this.store);

Looking up data stores

The Store manager’s lookup method gets a registered store by id.  The current implementation looks like this:

lookup : function(id){
    if(Ext.isArray(id)){
        var fields = ['field1'], expand = !Ext.isArray(id[0]);
        if(!expand){
            for(var i = 2, len = id[0].length; i <= len; ++i){
                fields.push('field' + i);
            }
        }
        return new Ext.data.ArrayStore({
            fields: fields,
            data: id,
            expandData: expand,
            autoDestroy: true,
            autoCreated: true
        });
    }
    return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
}

This look-up is what allows the component to locate its data store in the StoreMgr’s registry.   Note that lookup() also functions as a factory method, returning a new data store if the supplied id does not map to an existing one.

Want to learn more?

Check out my Ext JS 3.0 Cookbook.  It contains more than a hundred step-by-step recipes that explain useful techniques to build great Ext JS applications.

Comments