Search code examples
extjsdynamicextjs4storerenderer

Loading store dynamically based on visible page data for Ext.grid.Panel column


Below is a renderer for an Ext.grid.Panel column. Suppose contactStore has 2,000 values in it and all I care about is the name of the record based on the id (value parameter in this case), and my grid only has 25 rows/records in it for the page I'm on. How can I dynamically get the store so that I grab the relevant associated records (based on the foreign key) of the id of my grid column, rather than loading all 2,000 records? Is there a way to load the store and then in the callback, somehow have this "renderer" function display the values after the callback succeeded?

columns: [{

...

}, {
    header: 'Contact Name',
    flex: 1,
    sortable: true,
    dataIndex: 'contact_id',        
    renderer: function(value) {
        var contactStore = Ext.StoreManager.lookup('Contacts');
        return contactStore.getById(value).get('full_name');
    }
}, {

Solution

  • You can adjust the collectData(records, startIndex) in the viewConfig for that:

    Ext.create('Ext.grid.Panel', {
        (...)
        viewConfig: {
            //this method needs to be adjusted
            collectData: function(records, startIndex) {
                var me = this;
                //we can use a custom function for this
                if (me.onBeforeCollectData) {
                    me.onBeforeCollectData(records);
                }            
                var data = me.superclass.collectData.call(me, records, startIndex);
                return data;
            },
    
            onBeforeCollectData: function(records) {
                var newExtraParams = [];
                var oldExtraParams;
                var needToLoadStore = false;
                var contactStore = Ext.StoreManager.lookup('Contacts');         
    
                if (contactStore) {
                    oldExtraParams = contactStore.oldExtraParams;
                } else {
                    //don't use autLoad: true, this will be a local store
                    contactStore = Ext.create('Ext.data.Store', {
                        storeId:'Contacts',
                        (...)                   
                    });
                    needToLoadStore = true;
                }
    
                for (var x in records) {
                    //contact_id is read out here
                    var param = records[x].get('contact_id');
                    if (param) {
                        if (needToLoadStore == false && Ext.Array.contains(oldExtraParams, param) == false) {
                            needToLoadStore = true;
                        }
                        newExtraParams.push(param);
                    }                
                }           
    
                if (needToLoadStore == true) {
                    //we use this to load the store data => because of async: false property
                    Ext.Ajax.request({
                        scope: this,
                        //this is for synchronous calls
                        async: false,
                        url: (...),
                        method: (...),
                        params: newExtraParams,
                        success: function (res, opt) {
                            var responseObj = Ext.decode(res.responseText, false);
                            contactStore.loadData(responseObj); //or deeper in the responseObj if needed
                            contactStore.oldExtraParams = newExtraParams;
                        }
                    });
                }
            }
        }
    });