Как подождать, пока все магазины загрузятся в ExtJs?
У меня есть набор комбинированных ящиков, которые управляются пятью магазинами, и я хочу запустить функцию после того, как все магазины будут полностью загружены. Каков рекомендуемый способ сделать это? Я мог бы сделать что-то подобное, но он чувствует себя глупо:
var store1Loaded = false;
var store2Loaded = false;
store1.on('load', function(){
store1Loaded = true;
});
store2.on('load', function(){
store1Loaded = true;
});
store1.load();
store2.load();
function WaitForFunction()
{
if (!store1Loaded || !store2Loaded)) {
setTimeout( WaitForFunction, 100);
return;
}
AllStoresLoaded();
}
function AllStoresLoaded(){
//Do Something
}
Ответы
Ответ 1
Используйте метод store.isLoading()
, я думаю, для этого он и есть. Я использую его, и он отлично работает.
-
Настройте хранилища, которые вы хотите загрузить перед выполнением
некоторая логика с конфигурацией storeId
.
-
Поместите эти storeIds
в массив.
-
Всякий раз, когда один из этих магазинов загружается, итерации через массив, найдите хранилище с помощью Ext.getStore
и вызовите isLoading
на нем.
-
Если ни одна из массивов в массиве не загружается, выполните свою логику.
Например, скажите, что я хочу, чтобы 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
}
}
Ответ 2
Использование тайм-аутов не является отличным решением, однако также нужно полагаться на все, что есть в менеджере магазина.
Я бы сделал что-то вроде:
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
}
Если вы используете его много, вы можете даже превратить его в класс.
Ответ 3
Расширьте хранилище - добавьте свойство 'loaded' в дочерний класс, переопределите 'initComponent()' и присоединитесь к событию 'load' внутри него, поднимите "загружен" в true внутри обработчика событий, добавьте 'isLoaded()' метод возвращает значение свойства 'loaded'.
Другой способ, если вы используете http transport - store.proxy.conn.isLoading()
Взгляните на this
Ответ 4
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);
})
Ответ 5
Если у вас есть проблема, потому что combobox не отображаются/обновляться должным образом, когда магазины занимают слишком много времени для загрузки, решение заключается в создании каждого хранилища, которое должно быть использовано в combobox, таком как
Ext.create("Ext.data.Store", {
...,
loading: true,
...
});
Comboboxes проверяют этот параметр в магазинах, которые они используют для обновления информации после ее загрузки, но иногда сборка создается и обновляется даже до того, как магазин начинает загружаться, а флаг "загрузка" установлен в true, а затем он выиграл 't обновить его значение, когда магазин завершит загрузку.
Установка этого параметра в true явно устраняет проблему.
Я не знаю, было ли это ваше дело, но я думал, что упомянул об этом на случай.
Ответ 6
Использовать Deft JS
Deft JS - аддон, вводимый через инъекцию зависимости. Это позволяет пользователю добавлять promises в вызовы AJAX, и обещание разрешается только при выполнении вызова. Ссылка для Deft JS.
Используйте Ext.defer.All();, чтобы загрузить все ваши 5 магазинов, и определенная функция обратного вызова будет вызываться после загрузки всех магазинов. В этой функции выполните свою логику.
Ответ 7
У ExtJs Store есть метод 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);