如何等到所有商店都加载到 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

    如果数组中没有商店仍在加载,请执行您的逻辑。

例如,假设我希望在执行某些逻辑之前加载 store1store2(我以非 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&lt;ActionResult&gt; (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 中?的主要内容,如果未能解决你的问题,请参考以下文章

ExtJS 4:使用代理加载的数据存储显示 0 长度

Extjs 4.1 - 如何将数据从商店加载到另一个商店

加载商店后如何在网格中设置值? EXTJS3

ExtJS:使用一个网格加载多个商店

Extjs:加载商店时更改参数值

等待加载多个 ExtJS 存储