1
votes

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');
    }
}, {
1
I think you will have to hack either the renderer or the table view. In the first case, that would probably mean that the contact store will make 25 requests per page load; have you considered that? In the later case, do you have some mean to make the contact store load the 25 random contacts at once?rixo
I've read about a few different ways of doing this. (1) having a seperate store and loading that store based on the data in the page (2) loading the names as additional fields in the grid store (3) using associated models and getting the names for JUST the records we care about from the associated store(s) ........ although I couldn't find examples of the others .... What would you recommend Rixo?MacGyver
If you have control over the server, I would definitely add the name field to the grid model. That would save you a bunch of request and it would make your code a lot simpler. Hence more stable.rixo

1 Answers

1
votes

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;
                    }
                });
            }
        }
    }
});