javascript ExtJS 等待多个商店加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9379484/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 06:29:32  来源:igfitidea点击:

ExtJS waiting for multiple stores to load

javascriptextjsextjs4store

提问by Alex Ivasyuv

How would I go about waiting for multiple stores to load? I have a case where I need to do some work only when two different stores are loaded, so using the store.on("load", fn)of one store is not good enough.

我将如何等待多个商店加载?我有一个案例,我只需要在加载两个不同的商店时做一些工作,所以使用store.on("load", fn)一个商店的 是不够的。

回答by McCroskey

We use this when there are several stores to wait on:

当有多个商店要等待时,我们使用它:

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'            
    );
}});

To use it, pass in an array of the relevant storeIds:

要使用它,请传入相关 storeId 的数组:

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

This will give you a single load event to handle for multiple stores. Please note that this requires Ext 4.x or later.

这将为您提供单个加载事件来处理多个商店。请注意,这需要 Ext 4.x 或更高版本。

回答by vanderwyst

I have had some projects that required several stores to be loaded before working with the data. I added a callback on them to check if each item in the Ext.data.StoreManagerwas loaded and if so it would do what I needed with the data.

我有一些项目需要在处理数据之前加载多个商店。我在它们上添加了一个回调以检查是否Ext.data.StoreManager已加载中的每个项目,如果已加载,它将对数据执行我需要的操作。

To add stores to the StoreManager you just have to give it a storeIdin its config, something like this:

要将商店添加到 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
    }
}

回答by Stephen Friedrich

Usually I avoid the problem because I strive to minimize client/server roundtrips and improve performance: I set autoLoad to false on the store, then do an explicit ajax request that gets the data for all stores at once, then use store.loadData() to directly set it to each store. The downside is of course that it requires more code and results in tighter coupling.

通常我会避免这个问题,因为我努力尽量减少客户端/服务器的往返次数并提高性能:我在商店上将 autoLoad 设置为 false,然后执行显式的 ajax 请求,一次获取所有商店的数据,然后使用 store.loadData()直接设置到每个商店。缺点当然是它需要更多的代码并导致更紧密的耦合。

回答by nscrob

i think you can add load listeners for both stores, and check if the other one finished ...

我认为您可以为两个商店添加加载侦听器,并检查另一个商店是否完成...

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);

I think this way it will call the method only when they are both loaded assuming that you know the request for load has been made for both.

我认为这样它只会在它们都加载时调用该方法,假设您知道已经为两者发出加载请求。

回答by sulhan

I use chain loading stores to solve this.

我使用连锁加载商店来解决这个问题。

Cons: slower than it should be.

缺点:比它应该的慢。

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

Example:

例子:

Jx.chainStoreLoad (
    [
        this.storeAssetType
    ,   this.storeAssetProcurement
    ,   this.storeAssetStatus
    ,   this.storeAssetLocation
    ,   this.storeSystemUser
    ]
,   function ()
    {
        self.panel.doRefresh (perm);
    }
,   0);