ExtJS ждет загрузки нескольких магазинов - PullRequest
6 голосов
/ 21 февраля 2012

Как мне ждать загрузки нескольких магазинов?У меня есть случай, когда мне нужно выполнить какую-то работу, только когда загружены два разных магазина, поэтому использование store.on("load", fn) одного магазина недостаточно.

Ответы [ 5 ]

8 голосов
/ 28 июля 2013

Мы используем это, когда есть несколько магазинов, чтобы ждать:

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 или более поздняя версия.

4 голосов
/ 21 февраля 2012

У меня было несколько проектов, которые требовали загрузки нескольких хранилищ перед работой с данными. Я добавил к ним обратный вызов, чтобы проверить, был ли загружен каждый элемент в 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 голосов
/ 22 февраля 2012

Обычно я избегаю этой проблемы, потому что стараюсь свести к минимуму циклические обращения клиент-сервер и улучшить производительность: я устанавливаю для хранилища значение autoLoad, равное false, затем делаю явный запрос ajax, который получает данные для всех хранилищ одновременно, а затем использую хранилище.loadData (), чтобы напрямую установить его для каждого магазина.Недостатком является, конечно, то, что он требует больше кода и приводит к более жесткой связи.

1 голос
/ 23 мая 2014

Я использую магазины по загрузке цепей, чтобы решить эту проблему.

Минусы: медленнее, чем должно быть.

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);
1 голос
/ 21 февраля 2012

я думаю, что вы можете добавить загрузочные слушатели для обоих хранилищ и проверить, закончил ли другой ...

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

Я думаю, что таким образом он вызовет метод только тогда, когда они оба загружены, предполагая, чтоВы знаете, что запрос на загрузку был сделан для обоих.

...