2012-06-12 15 views
29

Mam zestaw pól kombi, które są napędzane przez pięć sklepów i chcę uruchomić funkcję, gdy wszystkie sklepy zostaną całkowicie załadowane. Jaki jest zalecany sposób robienia tego? Mogę zrobić coś takiego, ale czuje kludgy:Jak czekać na załadowanie wszystkich sklepów w 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 
} 

Odpowiedz

22

Użyj metody store.isLoading(), myślę, że do tego właśnie służy. Używam go i działa dobrze.

  1. Konfiguracja sklepy, które mają być załadowane przed wykonaniem jakiś logiczny z storeId config.

  2. Umieść te storeIds w tablicy.

  3. Ilekroć jeden z tych sklepów jest ładowany, należy przeprowadzić iterację w tablicy, odszukać w sklepie pod numerem Ext.getStore i zadzwonić pod numer isLoading.

  4. Jeśli żaden z sklepów w tablicy nadal nie jest ładowany, należy wykonać swoją logikę.

Załóżmy, że chcę store1 i store2 ładowane zanim wykonać jakąś logikę (pokazuję to w non-wzorca MVC, ponieważ wygląda na to, że nie korzysta z wzorca MVC fragmencie).

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

Czy 'isLoading()' 'równa FALSE gdy sklep nie jest załadowany? Czy to może być problem? –

+0

@o_nix według "nie załadowano" oznacza "nie ma zapisów"? Z mojego doświadczenia wynika, że ​​'isLoading' jest prawdziwe w czasie między żądaniem a odpowiedzią z serwera. Więc jeśli serwer nie zwróci żadnych rekordów, nadal będzie to prawda. To nigdy nie było dla mnie problemem. Głównym celem dla mnie jest po prostu wiedzieć, kiedy wniosek wraca. Można zastosować inną logikę, jeśli chcesz obsłużyć odpowiedź bez wyników. – Geronimo

+1

W celu sprawdzenia może zadziałać setTimeout (me.initData, 500). – VAAA

2

Rozszerz sklep - dodaj „załadowany” obiekt do klasy dziecięcej, override „initComponent()” i dołączyć do „obciążenie” zdarzenie wewnątrz it, podnieś "załadowany" do true wewnątrz obsługi zdarzenia, dodaj metodę zwracającą wartość 'isLoaded()' "załadowanej" właściwości.

inny sposób, jeśli używasz transportu HTTP - store.proxy.conn.isLoading()

Spójrz na this

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

Korzystanie limity czasu nie jest doskonałym rozwiązaniem, jednak również poleganie na wszystkim w kierowniku sklepu też nie jest wspaniałe.

zrobiłbym coś takiego:

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 
} 

Jeśli używasz to ma dużo można nawet przekształcić go w klasie.

2

Jeśli masz problem, ponieważ combobox nie są wyświetlane/odświeżane poprawnie, gdy przechowuje się zbyt długo, aby załadować, rozwiązaniem jest utworzenie każdym sklepie, który ma być używany w combobox jak ten

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

Comoboxy sprawdzają parametr w sklepach, których używają do odświeżenia informacji po jej załadowaniu, ale czasami combobox jest tworzony i odświeżany, zanim sklep zacznie się ładować i flaga 'loading' jest ustawiona na true, a następnie nie odświeży swojej wartości, gdy magazyn zakończy ładowanie. Ustawienie na wartość true wyraźnie rozwiązuje problem. Nie wiem, czy to twoja sprawa, ale pomyślałem, że wspomnę o tym na wszelki wypadek.

+0

Mieliśmy dokładnie problem, ponieważ nasz ViewModel został zwrócony jako 'async Task ' (Asp.Net MVC) i comboboxes próbowali ustawić swoje wartości, zanim załadowano ich magazyny. Ustawienie 'loading: true' całkowicie rozwiązało problem. – mdisibio

+0

To zaoszczędziło mi mnóstwo czasu/kodu. Mamy taki sam warunek "wyścigu" sklepu combobox, w którym formowanie wiązań ma miejsce, zanim combobox załaduje swój sklep. Znalazłem ten wątek myśląc, że będę musiał napisać kod klienta, aby czekać na załadowanie wszystkich sklepów, zanim przejdę do moich operacji form.loadRecord. Ta prosta konfiguracja sklepu naprawiła problem. Wielkie dzięki! –

1

Zastosowanie Deft JS

Deft JS dodatek jest wtryskiwany przez dependancy iniekcji. Pozwala użytkownikowi dodawać obietnice w połączeniach AJAX, a obietnica zostaje rozwiązana dopiero po zakończeniu połączenia. Link for Deft JS. Użyj Ext.defer.All();, aby załadować wszystkie twoje 5 sklepów, a określona funkcja wywołania zwrotnego zostanie wywołana po załadowaniu wszystkich sklepów. W tej funkcji Wprowadź swoją logikę.

1

Sklep ExtJs ma metodę load, a metoda ładowania ma funkcję zwrotną.

Utworzyłem wersję demo. możesz sprawdzić tutaj: Sencha fiddle

Ta funkcja spowoduje utworzenie magazynu i zwrot.

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

Na przykład mam tablicę sklepie. Zawiera storeId lub alias.

var storeArry = [], 
    store = ''; 

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

Na każdym sklepie zwrotnego możemy usunąć dane z storeArray lub utrzymania zmiennej do sprawdzenia.

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); 
Powiązane problemy