2012-02-21 6 views
6

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

+0

Связанные с http://stackoverflow.com/questions/11003605/how-to-wait-until-all-stores-are-loaded-in-extjs – Patrick

ответ

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

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

Не конечно, но я думаю, что downvote был вызван 'loaded =! store.isLoading();' который должен быть 'loaded & =! store.isLoading();'. См. Это [jsfiddle] (http://jsfiddle.net/JHMzp/1). В любом случае должен быть комментарий, чтобы помочь нам всем :) – aletzo

1

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

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 или новее.

+0

Отлично! спасибо – Black

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); 
Смежные вопросы