¿Cómo esperar hasta que todas las tiendas estén cargadas en ExtJs?

Tengo un conjunto de cuadros combinados controlados por cinco tiendas y quiero activar una función una vez que todas las tiendas estén completamente cargadas. ¿Cuál es la forma recomendada de hacer esto? Podría hacer algo como esto, pero se siente confuso:

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
}

preguntado el 12 de junio de 12 a las 20:06

7 Respuestas

Use el store.isLoading() método, creo que para eso sirve. Yo lo uso y funciona bien.

  1. Configure las tiendas que desea que se carguen antes de realizar alguna lógica con un storeId config.

  2. Pon estos storeIds en una matriz.

  3. Cada vez que se cargue una de estas tiendas, itere a través de la matriz, busque la tienda con Ext.getStore y llama isLoading en ella.

  4. Si ninguna de las tiendas en la matriz aún se está cargando, realice su lógica.

Por ejemplo, di que quiero store1 y store2 cargado antes de realizar algo de lógica (estoy mostrando esto en un patrón que no es MVC porque parece que no está usando el patrón MVC de su fragmento).

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

contestado el 21 de mayo de 20 a las 21:05

¿Afecta la regulación de la isLoading() igual false cuando la tienda no está cargada? ¿Podría ser un problema? - o_nix

@o_nix por "no cargado" ¿quiere decir "no tiene registros"? En mi experiencia isLoading solo es igual a verdadero en el tiempo entre una solicitud y una respuesta del servidor. Entonces, si un servidor no devuelve registros, aún sería cierto. Esto nunca ha sido un problema para mí. El punto principal para mí es simplemente saber cuándo regresa la solicitud. Se podría implementar una lógica diferente si desea manejar una respuesta sin resultados. - egerardus

Para seguir comprobando, tal vez setTimeout(me.initData,500) debería funcionar. - VAAA

@VAAA El objetivo de esto no es tener que seguir comprobando con un temporizador, initData se llama cada vez que una de las tiendas termina de cargar porque está en el load configuración Cuando se llama, comprueba si todas las demás tiendas han terminado de cargarse, si es verdadero, realiza la lógica necesaria: egerardus

Usar tiempos de espera no es una gran solución, sin embargo, tener que depender de todo en el administrador de la tienda tampoco es excelente.

Haría algo como:

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 lo estás usando mucho, incluso podrías convertirlo en una clase.

Respondido el 12 de junio de 12 a las 23:06

Extienda la tienda: agregue la propiedad 'cargado' a la clase secundaria, anule 'initComponent()' y adjúntelo al evento 'cargar' dentro de él, eleve el 'cargado' a verdadero dentro del controlador de eventos, agregue 'isLoaded()' método que devuelve el valor de la propiedad 'cargada'.

De otra manera, si usa el transporte http - store.proxy.conn.isLoading()

Echa un vistazo a este

Respondido el 12 de junio de 12 a las 20:06

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

Respondido el 12 de junio de 12 a las 21:06

Si tiene un problema porque el cuadro combinado no se muestra/actualiza correctamente cuando las tiendas tardan demasiado en cargarse, la solución es crear cada tienda que se utilizará en un cuadro combinado como este

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

Los cuadros combinados verifican ese parámetro en las tiendas que usan para actualizar la información una vez que se carga, pero a veces el cuadro combinado se crea y se actualiza incluso antes de que la tienda comience a cargarse y el indicador de "carga" se establece en verdadero, y luego no se actualizará su valor cuando la tienda termine de cargar. Establecerlo en verdadero soluciona explícitamente el problema. No sé si ese es tu caso, pero pensé en mencionarlo en caso de que lo sea.

Respondido el 17 de enero de 14 a las 11:01

Tuvimos el problema exacto porque nuestro ViewModel se devolvió como async Task<ActionResult> (Asp.Net MVC) y los cuadros combinados intentaban establecer sus valores antes de cargar sus tiendas. Ajuste loading:true solucionó absolutamente el problema. - mdisibio

Esto me ahorró una tonelada de tiempo/código. Tenemos la misma condición de "carrera" de la tienda del cuadro combinado en la que se vincula el formulario antes de que el cuadro combinado haya cargado su tienda. Encontré este hilo pensando que iba a tener que escribir el código del cliente para esperar a que se cargaran todas las tiendas antes de continuar con mis operaciones form.loadRecord. Esta configuración de tienda simple solucionó el problema de inmediato. ¡Muchas gracias! - Abeja zancuda

Usar hábil JS

Deft JS es un complemento inyectado mediante inyección de dependencia. Permite al usuario agregar promesas en llamadas AJAX y la promesa se resuelve solo cuando finaliza la llamada. Enlace para Deft JS. Usar Ext.defer.All(); para cargar todas sus 5 tiendas y se llamará a una función de devolución de llamada particular una vez que todas las tiendas estén cargadas. En esa función, implemente su lógica.

respondido 27 mar '16, 16:03

ExtJs Store tiene método carga y el método de carga tienen función de devolución de llamada.

He creado una demostración. puedes comprobar aquí violín sencha

Esta función creará tienda y devolución.

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'
            }
        }
    });
}

Por ejemplo, tengo una matriz de tienda. Contiene storeId o alias.

var storeArry = [],
    store = '';

for (var key = 0; key < 5; key++) {
    storeArry.push(createStore(key).storeId);
}

En cada devolución de llamada de la tienda, podemos eliminar datos de storeArray o mantener una variable para verificar.

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);

Respondido el 20 de Septiembre de 17 a las 08:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.