我有一组由五个商店驱动的组合框,我想在所有商店完全加载后触发一个功能。推荐的方法是什么?我可以做这样的事情,但感觉很笨拙:
var store1Loaded = false;
var store2Loaded = false;
store1.on('load', function(){
store1Loaded = true;
});
store2.on('load', function(){
store2Loaded = true;
});
store1.load();
store2.load();
function WaitForFunction()
{
if (!store1Loaded || !store2Loaded)) {
setTimeout( WaitForFunction, 100);
return;
}
AllStoresLoaded();
}
function AllStoresLoaded(){
//Do Something
}
store.isLoading()
方法,我认为这就是它的用途。我用它并且效果很好。
执行前配置好要加载的store 一些带有
storeId
配置的逻辑。将这些
storeIds
放入数组中。每当加载这些存储之一时,都会迭代数组,使用
Ext.getStore
查找该存储并对其调用 isLoading
。如果数组中没有任何商店仍在加载,请执行您的逻辑。
例如,假设我希望在执行某些逻辑之前加载
store1
和 store2
(我以非 MVC 模式显示此内容,因为它看起来您没有使用代码片段中的 MVC 模式)。
var store1 = Ext.create('Ext.data.Store', {
model: myModel,
storeId: 'store1', // store needs to be done MVC style or have this config
proxy: {
type: 'ajax',
url: 'url...',
reader: 'json'
},
autoLoad: {
callback: initData // do this function when it loads
}
});
var store2 = Ext.create('Ext.data.Store', {
model: myModel,
storeId: 'store2',
proxy: {
type: 'ajax',
url: 'url...',
reader: 'json'
},
autoLoad: {
callback: initData // do this function when it loads
}
});
// the stores to be checked
var myComboStores = ['store1', 'store2']
// function does logic if they are both finished loading
function initData() {
var loaded = true;
Ext.each(myComboStores, function(storeId) {
var store = Ext.getStore(storeId);
if (store.isLoading()) {
loaded = false;
}
});
if(loaded) {
// do stuff with the data
}
}
使用超时并不是一个很好的解决方案,但是必须依赖商店管理器中的所有内容也不是很好。
我会做类似的事情:
var allStores = [store1, store2],
len = allStores.length,
loadedStores = 0,
i = 0;
for (; i < len; ++i) {
allStores[i].on('load', check, null, {single: true});
}
function check() {
if (++loadedStores === len) {
AllStoresLoaded();
}
}
function AllStoresLoaded() {
//Do Something
}
如果您经常使用它,您甚至可以将其变成一个类。
扩展存储 - 将 'loaded' 属性添加到子类中, 覆盖“initComponent()”并附加到其中的“load”事件,引发 在事件处理程序中将“loaded”设置为 true,添加“isLoaded()” 方法返回“loaded”属性的值。
另一种方式,如果您使用http传输 - store.proxy.conn.isLoading()
看看这个
function storeLoadingHandler(justLoadedStore) {
// I use some quick hacky flag, you can do it by your own way
justLoadedStore.loaded = true;
var allStoresLoaded = true;
// just walk through all stores registered in the application
// do not forget to use MVC-style stores or add 'storeId' manually
// or register every store with your custom code
Ext.StoreManager.each(function(existingStore) {
// we have to ignore system stores
if (existingStore.storeId != 'ext-empty-store') {
if (!existingStore.loaded) { // our flag or undefined
// nope, at least one of stores is not loaded
allStoresLoaded = false;
return false
}
}
})
if (allStoresLoaded) // then do something
alert('All stores are loaded.');
}
// add the loading handler for all stores
Ext.StoreManager.each(function() {
this.on('load', storeLoadingHandler);
})
如果您遇到问题,因为当商店加载时间太长时,组合框无法正确显示/刷新,解决方案是创建要在这样的组合框中使用的每个商店
Ext.create("Ext.data.Store", {
...,
loading: true,
...
});
组合框在加载后检查它们用来刷新信息的商店中的参数,但有时甚至在商店开始加载并且“正在加载”标志设置为 true 之前就创建并刷新了组合框,然后它就不会当商店加载完成时刷新其值。 将其设置为 true 可以明确解决该问题。 我不知道这是否是你的情况,但我想我会提到它,以防万一。
使用 Deft JS
Deft JS 是通过依赖注入注入的插件。它允许用户在 AJAX 调用中添加承诺,并且只有在调用完成时承诺才会得到解决。 Deft JS 链接。 使用 Ext.defer.All(); 加载所有 5 个商店,一旦所有商店加载完毕,将调用特定的回调函数。在该函数中,实现您的逻辑。
ExtJs Store 有方法 load 并且 load 方法有回调函数。
我创建了一个演示。你可以在这里查看Sencha小提琴
此函数将创建存储并返回。
function createStore(id) {
return Ext.create('Ext.data.Store', {
storeId: 'store_' + id,
alias: 'store.store_' + id,
proxy: {
type: 'ajax',
url: 'data.json',
timeout: 300000,
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
}
例如,我有商店数组。它包含 storeId 或别名。
var storeArry = [],
store = '';
for (var key = 0; key < 5; key++) {
storeArry.push(createStore(key).storeId);
}
在每个存储回调中,我们可以从 storeArray 中删除数据或维护一个变量进行检查。
Ext.getBody().mask('Please wait..');
Ext.defer(function () {
Ext.getBody().unmask();
Ext.Array.forEach(storeArry, function (storeId) {
//For checking store is created or not
//if store is not created we can create dyanamically using passing storeId/alias
store = Ext.getStore(storeId);
if (Ext.isDefined(store) == false) {
store = Ext.create(storeId);
}
store.load({
callback: function () {
//On every store call back we can remove data from storeArray or maintain a veribale for checking.
Ext.Array.remove(storeArry, this.storeId);
if (storeArry.length == 0) {
Ext.Msg.alert('Success', 'All stored is loaded..!');
}
}
});
});
}, 3000);