我如何等待多个商店加载?我有一个案例,我只有在加载两个不同的商店时才需要做一些工作,所以使用一个商店的store.on("load", fn)
是不够的。
答案 0 :(得分:8)
当有几家商店要等待时,我们会使用这个:
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'
);
}});
要使用它,请传入相关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
}
}
});
这将为您提供单个加载事件来处理多个商店。请注意,这需要Ext 4.x或更高版本。
答案 1 :(得分:4)
我有一些项目需要在处理数据之前加载几个商店。我在它们上面添加了一个回调函数来检查Ext.data.StoreManager
中的每个项目是否都已加载,如果是这样的话,它会根据我的数据进行操作。
要将商店添加到StoreManager,您只需在其配置中为其指定storeId
,如下所示:
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
}
}
答案 2 :(得分:2)
通常我会避免这个问题,因为我努力减少客户端/服务器往返次数并提高性能: 我在商店中将autoLoad设置为false,然后执行显式的ajax请求,一次获取所有商店的数据,然后使用store.loadData()直接将其设置为每个商店。 缺点当然是它需要更多的代码并导致更紧密的耦合。
答案 3 :(得分:1)
我认为你可以为两个商店添加加载监听器,并检查另一个商店是否已完成......
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);
我认为这种方式只有当它们都被加载时它才会调用该方法,假设您已经知道了对两者的加载请求。
答案 4 :(得分:1)
我使用连锁加载商店来解决这个问题。
缺点:比它应该慢。
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);
});
}
示例:
Jx.chainStoreLoad (
[
this.storeAssetType
, this.storeAssetProcurement
, this.storeAssetStatus
, this.storeAssetLocation
, this.storeSystemUser
]
, function ()
{
self.panel.doRefresh (perm);
}
, 0);