Подтвердить что ты не робот

Как подождать, пока все магазины загрузятся в 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
}
4b9b3361

Ответ 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);