如何等待ExtJs中所有商店加载完毕?

问题描述 投票:0回答:7

我有一组由五个商店驱动的组合框,我想在所有商店完全加载后触发一个功能。推荐的方法是什么?我可以做这样的事情,但感觉很笨拙:

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
}
extjs
7个回答
26
投票

使用

store.isLoading()
方法,我认为这就是它的用途。我用它并且效果很好。

  1. 执行前配置好要加载的store 一些带有

    storeId
    配置的逻辑。

  2. 将这些

    storeIds
    放入数组中。

  3. 每当加载这些存储之一时,都会迭代数组,使用

    Ext.getStore
    查找该存储并对其调用
    isLoading

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

例如,假设我希望在执行某些逻辑之前加载

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
    }
}

8
投票

使用超时并不是一个很好的解决方案,但是必须依赖商店管理器中的所有内容也不是很好。

我会做类似的事情:

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
}

如果您经常使用它,您甚至可以将其变成一个类。


2
投票

扩展存储 - 将 'loaded' 属性添加到子类中, 覆盖“initComponent()”并附加到其中的“load”事件,引发 在事件处理程序中将“loaded”设置为 true,添加“isLoaded()” 方法返回“loaded”属性的值。

另一种方式,如果您使用http传输 - store.proxy.conn.isLoading()

看看这个


2
投票
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);
})

2
投票

如果您遇到问题,因为当商店加载时间太长时,组合框无法正确显示/刷新,解决方案是创建要在这样的组合框中使用的每个商店

Ext.create("Ext.data.Store", {
    ...,
    loading: true,
    ...
});

组合框在加载后检查它们用来刷新信息的商店中的参数,但有时甚至在商店开始加载并且“正在加载”标志设置为 true 之前就创建并刷新了组合框,然后它就不会当商店加载完成时刷新其值。 将其设置为 true 可以明确解决该问题。 我不知道这是否是你的情况,但我想我会提到它,以防万一。


1
投票

使用 Deft JS

Deft JS 是通过依赖注入注入的插件。它允许用户在 AJAX 调用中添加承诺,并且只有在调用完成时承诺才会得到解决。 Deft JS 链接。 使用 Ext.defer.All(); 加载所有 5 个商店,一旦所有商店加载完毕,将调用特定的回调函数。在该函数中,实现您的逻辑。


1
投票

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);
© www.soinside.com 2019 - 2024. All rights reserved.