如何等到所有商店都加载到 ExtJs 中?
Posted
技术标签:
【中文标题】如何等到所有商店都加载到 ExtJs 中?【英文标题】:How to wait until all stores are loaded in ExtJs? 【发布时间】:2012-06-12 19:36:52 【问题描述】:我有一组由五个商店驱动的组合框,我想在所有商店完全加载后触发一个函数。这样做的推荐方法是什么?我可以做这样的事情,但感觉很笨拙:
var store1Loaded = false;
var store2Loaded = false;
store1.on('load', function()
store1Loaded = true;
);
store2.on('load', function()
store1Loaded = true;
);
store1.load();
store2.load();
function WaitForFunction()
if (!store1Loaded || !store2Loaded))
setTimeout( WaitForFunction, 100);
return;
AllStoresLoaded();
function AllStoresLoaded()
//Do Something
【问题讨论】:
【参考方案1】:使用store.isLoading()
方法,我认为这就是它的用途。我使用它,它工作正常。
在执行之前配置要加载的商店
一些带有storeId
配置的逻辑。
将这些storeIds
放入一个数组中。
每当加载这些存储中的一个时,迭代数组,使用Ext.getStore
查找存储并在其上调用isLoading
。
如果数组中没有商店仍在加载,请执行您的逻辑。
例如,假设我希望在执行某些逻辑之前加载 store1
和 store2
(我以非 MVC 模式显示此内容,因为看起来您没有使用 sn-p 中的 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
【讨论】:
当 store 未加载时,isLoading()
是否等于 false
?会不会有问题?
@o_nix “未加载”是指“没有记录”吗?根据我的经验,isLoading
仅在请求和服务器响应之间的时间内等于 true。因此,如果服务器不返回任何记录,那么它仍然是正确的。这对我来说从来都不是问题。对我来说,它的主要目的只是知道请求何时返回。如果您想处理没有结果的响应,可以实现不同的逻辑。
为了继续检查 setTimeout(me.initData,500) 应该可以工作。
@VAAA 重点是不必继续检查计时器,只要其中一个商店完成加载,就会调用initData
,因为它位于load
配置中。当它被调用时,它会检查所有其他商店是否已完成加载,如果为 true,它会执行所需的任何逻辑【参考方案2】:
使用超时不是一个很好的解决方案,但也必须依赖 store manager 中的所有内容也不是很好。
我会这样做:
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
如果你经常使用它,你甚至可以把它变成一个类。
【讨论】:
【参考方案3】:扩展存储 - 将 'loaded' 属性添加到子类, 覆盖'initComponent()'并附加到其中的'load'事件,引发 在事件处理程序中将'loaded'设置为true,添加'isLoaded()' 方法返回“加载”属性的值。
其他方式,如果您使用 http 传输 - store.proxy.conn.isLoading()
看看this
【讨论】:
【参考方案4】: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);
)
【讨论】:
【参考方案5】:如果您遇到问题,因为当商店加载时间过长时组合框没有正确显示/刷新,解决方案是创建要在这样的组合框中使用的每个商店
Ext.create("Ext.data.Store",
...,
loading: true,
...
);
组合框在加载后会检查它们用来刷新信息的商店中的参数,但有时组合框甚至在商店开始加载并且“加载”标志设置为 true 之前就已创建和刷新,然后它就赢了'当商店完成加载时不刷新它的值。 将其设置为 true 可以明确解决此问题。 我不知道这是否是你的情况,但我想我会提到它以防万一。
【讨论】:
我们遇到了确切的问题,因为我们的 ViewModel 以async Task<ActionResult>
(Asp.Net MVC) 的形式返回,并且组合框试图在加载它们的商店之前设置它们的值。设置loading:true
绝对解决了这个问题。
这为我节省了大量时间/代码。我们有相同的组合框存储“竞争”条件,即在组合框加载其存储之前发生表单绑定。我发现这个线程认为我将不得不编写客户代码来等待所有商店加载,然后再继续我的 form.loadRecord 操作。这个简单的商店配置立即解决了问题。非常感谢!【参考方案6】:
使用 Deft JS
Deft JS 是一个通过依赖注入注入的插件。它允许用户在 AJAX 调用中添加 Promise,并且只有在调用完成时才会解析 Promise。 Link for Deft JS。 使用 Ext.defer.All(); 加载所有 5 个商店,一旦加载所有商店,就会调用一个特定的回调函数。在那个函数中,实现你的逻辑。
【讨论】:
【参考方案7】:ExtJs Store 有方法 load 和 load 方法有回调函数。
我创建了一个演示。你可以在这里查看Sencha fiddle
此函数将创建存储并返回。
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);
【讨论】:
以上是关于如何等到所有商店都加载到 ExtJs 中?的主要内容,如果未能解决你的问题,请参考以下文章