How would I go about waiting for multiple stores to load? I have a case where I need to do some work only when two different stores are loaded, so using the store.on("load", fn)
of one store is not good enough.
We use this when there are several stores to wait on:
Ext.define('Ext.ux.StoreLoadCoordinator', {
mixins: {
observable: 'Ext.util.Observable'
},
resetStoreLoadStates: function() {
this.storeLoadStates = {};
Ext.each(this.stores, function(storeId) {
this.storeLoadStates[storeId] = false;
}, this);
},
isLoadingComplete: function() {
for (var i=0; i<this.stores.length; i++) {
var key = this.stores[i];
if (this.storeLoadStates[key]==false) {
return false;
}
}
return true;
},
onStoreLoad: function(store, records, successful, eOpts, storeName) {
this.storeLoadStates[store.storeId] = true;
if (this.isLoadingComplete()==true) {
this.fireEvent('load');
this.resetStoreLoadStates();
}
},
constructor: function (config) {
this.mixins.observable.constructor.call(this, config);
this.resetStoreLoadStates();
Ext.each(this.stores, function(storeId) {
var store = Ext.StoreManager.lookup(storeId);
store.on('load', Ext.bind(this.onStoreLoad, this, [storeId], true));
}, this);
this.addEvents(
'load'
);
}});
To use it, pass in an array of the relevant storeIds:
var store1 = Ext.create('Ext.data.Store', {
storeId: 'Store1',
.... (rest of store config)
}});
var store2 = Ext.create('Ext.data.Store', {
storeId: 'Store2',
.... (rest of store config)
}});
var coordinatior = Ext.create('Ext.ux.StoreLoadCoordinator', {
stores: ['Store1', 'Store2'],
listeners: {
load: function() {
// Do post-load work
}
}
});
This will give you a single load event to handle for multiple stores. Please note that this requires Ext 4.x or later.
I have had some projects that required several stores to be loaded before working with the data. I added a callback on them to check if each item in the Ext.data.StoreManager
was loaded and if so it would do what I needed with the data.
To add stores to the StoreManager you just have to give it a storeId
in its config, something like this:
var store1 = Ext.create('Ext.data.Store', {
model: myModel,
storeId: 'store1', //<-- adds this to Ext.data.StoreManager
proxy: {
type: 'ajax',
url: 'url...',
reader: 'json'
},
autoLoad: {
callback: initData
}
});
var store2 = Ext.create('Ext.data.Store', {
model: myModel,
storeId: 'store2',
proxy: {
type: 'ajax',
url: 'url...',
reader: 'json'
},
autoLoad: {
callback: initData
}
});
// Initialize store dependencies when all stores are loaded
function initData() {
var loaded;
Ext.data.StoreManager.each( function(store) {
loaded = !store.isLoading();
return loaded;
});
if(loaded) {
// do stuff with the data
}
}
Usually I avoid the problem because I strive to minimize client/server roundtrips and improve performance: I set autoLoad to false on the store, then do an explicit ajax request that gets the data for all stores at once, then use store.loadData() to directly set it to each store. The downside is of course that it requires more code and results in tighter coupling.
i think you can add load listeners for both stores, and check if the other one finished ...
this.getStore('store1').on('load',function(store){
if (this.getStore('store2').isLoading() == false ){
// callMethod to perform action ....
}
},this);
this.getStore('store2').on('load',function(store){
if (this.getStore('store1').isLoading() == false ){
// callMethod to perform action....
}
},this);
I think this way it will call the method only when they are both loaded assuming that you know the request for load has been made for both.
I use chain loading stores to solve this.
Cons: slower than it should be.
chainStoreLoad :function (stores, lastCall, idx)
{
if (idx === stores.length) {
if ("function" === typeof lastCall) {
lastCall.call ();
}
return;
}
stores[idx].load (function (r,o,s) {
Jx.chainStoreLoad (stores, lastCall, idx + 1);
});
}
Example:
Jx.chainStoreLoad (
[
this.storeAssetType
, this.storeAssetProcurement
, this.storeAssetStatus
, this.storeAssetLocation
, this.storeSystemUser
]
, function ()
{
self.panel.doRefresh (perm);
}
, 0);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With