32 votes

Comment attendre que tous les magasins soient chargés dans ExtJs ?

J'ai un ensemble de boîtes combo qui sont pilotées par cinq magasins et je veux lancer une fonction une fois que tous les magasins sont complètement chargés. Quelle est la méthode recommandée pour ce faire ? Je pourrais faire quelque chose comme ça, mais c'est un peu compliqué :

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
}

26voto

Geronimo Points 6482

Utilisez le store.isLoading() méthode, je pense que c'est à cela qu'elle sert. Je l'utilise et ça marche bien.

  1. Configurez les magasins que vous voulez charger avant d'exécuter une logique avec un storeId config.

  2. Mettez ces storeIds dans un tableau.

  3. Chaque fois qu'un de ces magasins est chargé, il faut itérer dans le tableau, rechercher le magasin à l'aide de la commande Ext.getStore et appeler isLoading sur elle.

  4. Si aucun des magasins du tableau n'est encore en cours de chargement, exécutez votre logique.

Par exemple, disons que je veux store1 y store2 chargé avant d'exécuter une certaine logique (je montre ceci dans le modèle non-MVC parce qu'il semble que vous n'utilisez pas le modèle MVC d'après votre extrait).

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

8voto

Evan Trimboli Points 15857

L'utilisation de délais d'attente n'est pas une solution idéale, mais le fait de devoir se fier à tout ce qui se trouve dans le gestionnaire de magasin ne l'est pas non plus.

Je ferais quelque chose comme :

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
}

Si vous l'utilisez beaucoup, vous pouvez même en faire un cours.

2voto

pacman Points 625

Étendez le magasin - ajoutez la propriété "loaded" à la classe enfant, surchargez 'initComponent()' et attachez l'événement 'load' à l'intérieur, augmentez la valeur de l'événement "loaded" à true dans le gestionnaire d'événements, ajoutez la méthode "isLoaded()". qui renvoie la valeur de la propriété "loaded".

Autre moyen, si vous utilisez le transport http - store.proxy.conn.isLoading()

Jetez un coup d'œil à ce

2voto

o_nix Points 907
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);
})

2voto

Triqui Points 41

Si vous avez un problème parce que la combobox ne s'affiche pas/se rafraîchit correctement lorsque les magasins prennent trop de temps à se charger, la solution est de créer chaque magasin qui doit être utilisé dans une combobox comme ceci

Ext.create("Ext.data.Store", {
    ...,
    loading: true,
    ...
});

Les combobox vérifient ce paramètre dans les magasins qu'ils utilisent pour rafraîchir les informations une fois qu'elles sont chargées, mais il arrive que la combobox soit créée et rafraîchie avant même que le magasin ne commence à se charger et que l'indicateur "loading" soit défini sur true, et qu'elle ne rafraîchisse pas sa valeur à la fin du chargement du magasin. En lui attribuant explicitement la valeur true, le problème est résolu. Je ne sais pas si c'est votre cas, mais j'ai pensé le mentionner au cas où ce serait le cas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X