ExtJS等待多个商店加载

时间:2012-02-21 14:43:56

标签: javascript extjs extjs4 store

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

5 个答案:

答案 0 :(得分:8)

当有几家商店要等待时,我们会使用这个:

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

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

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

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

答案 1 :(得分:4)

我有一些项目需要在处理数据之前加载几个商店。我在它们上面添加了一个回调函数来检查Ext.data.StoreManager中的每个项目是否都已加载,如果是这样的话,它会根据我的数据进行操作。

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

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

我认为这种方式只有当它们都被加载时它才会调用该方法,假设您已经知道了对两者的加载请求。

答案 4 :(得分:1)

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

缺点:比它应该慢。

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

示例:

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