J'ai un ensemble de boîtes à options pilotées par cinq magasins et je souhaite activer une fonction une fois que tous les magasins sont complètement chargés. Quelle est la façon recommandée de faire cela? Je pourrais faire quelque chose comme ça, mais ça fait kludgy:
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
}
Utilisez la méthode store.isLoading()
, je pense que c’est à quoi cela sert. Je l'utilise et ça marche bien.
Configurez les magasins que vous voulez charger avant d’exécuter Une logique avec un storeId
config.
Mettez ces storeIds
dans un tableau.
Chaque fois que l'un de ces magasins est chargé, parcourez le tableau, recherchez-le avec Ext.getStore
et appelez isLoading
.
Si aucun des magasins de la matrice ne se charge toujours, exécutez votre logique.
Par exemple, disons que je veux que store1
et store2
soient chargés avant d'exécuter une logique (je montre cela dans un modèle non MVC car il semble que vous n'utilisez pas le modèle MVC de 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
}
}
Utiliser les délais d'attente n'est pas une bonne solution, mais il faut aussi compter sur tout ce qui se trouve dans le gérant du magasin.
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 le transformer en classe.
Étendre le magasin - ajoutez la propriété 'chargée' à la classe enfant, écrasez 'initComponent ()' et attachez-le à l'événement 'load' à l'intérieur, relancez le "chargé" à true dans le gestionnaire d'événements, ajoutez le "isLoaded ()" méthode renvoyant la valeur de la propriété 'chargée'.
Autre moyen, si vous utilisez http transport - store.proxy.conn.isLoading ()
Regardez this
Si vous rencontrez un problème parce que les listes déroulantes ne sont pas affichées/actualisées correctement lorsque le chargement des magasins est trop long, la solution consiste à créer chaque magasin devant être utilisé dans une liste déroulante comme celle-ci.
Ext.create("Ext.data.Store", {
...,
loading: true,
...
});
Les combobox vérifient ce paramètre dans les magasins qu'ils utilisent pour actualiser les informations une fois chargées, mais parfois, la liste déroulante est créée et actualisée avant même que le magasin ne commence à se charger et que l'indicateur 'loading' est défini sur true. sa valeur lorsque le magasin a fini de charger . Régler sur true corrige explicitement le problème .. Je ne sais pas si c'est votre cas, mais je pensais le mentionner dans le cas contraire.
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);
})
ExtJs Store a la méthode load et la méthode load a la fonction de rappel.
J'ai créé une démo. vous pouvez vérifier ici Violon Sencha
Cette fonction va créer magasin et retour.
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'
}
}
});
}
Par exemple, j'ai un tableau de magasin. Il contient storeId ou alias.
var storeArry = [],
store = '';
for (var key = 0; key < 5; key++) {
storeArry.Push(createStore(key).storeId);
}
Sur chaque rappel de magasin, nous pouvons supprimer des données de storeArray ou maintenir une variable à vérifier.
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);
Use Deft JS
Deft JS est un addon injecté via une injection de dépendance. Il permet à l'utilisateur d'ajouter des promesses dans les appels AJAX et la promesse n'est résolue que lorsque l'appel est terminé. Lien pour Deft JS . Utilisez Ext.defer.All (); pour charger tous vos 5 magasins et une fonction de rappel particulière sera appelée une fois que tous les magasins sont chargés. Dans cette fonction, implémentez votre logique.