2012-06-12 58 views
29

我有一組由五家商店驅動的組合框,我想在所有商店完全加載後啓動一個功能。推薦的方法是什麼?我可以做這樣的事情,但感覺缺憾:如何等待所有商店加載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 
} 

回答

22

使用store.isLoading()方法,我認爲這是它的目的。我使用它,它工作正常。

  1. 配置所需的商店與storeId配置進行 一些邏輯之前加載。

  2. 將這些storeIds放入數組中。

  3. 無論何時加載這些商店中的一個,都會遍歷整個數組,然後查找商店並使用Ext.getStore並調用isLoading就可以了。

  4. 如果陣列中沒有任何商店仍在加載,請執行您的邏輯。

例如,假設我想store1store2加載之前我進行一些邏輯(我顯示這個非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 
    } 
} 
+0

是否'isLoading()''等於沒有裝入存儲時FALSE'?這可能是一個問題嗎? –

+0

@o_nix by「not loaded」你的意思是「沒有記錄」?根據我的經驗,'isLoading'只在從服務器發出請求和響應之間的時間內等於true。所以如果服務器沒有返回記錄,那麼它仍然是真的。這對我來說從來都不是問題。它的主要觀點是簡單地知道請求何時返回。如果你想處理沒有結果的響應,可以實現不同的邏輯。 – Geronimo

+1

爲了保持檢查可能setTimeout(me.initData,500)應該工作。 – VAAA

2

延長貯藏室 - 「裝」屬性添加到子類, 覆蓋「initComponent()」,重視「負荷」內事件它將 的'loaded'設置爲事件處理程序中的true,添加'isLoaded()' 方法返回'loaded'屬性的值。

其他方式,如果你使用HTTP傳輸 - store.proxy.conn.isLoading()

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

使用超時是不是一個偉大的解決方案,但是也不得不依賴商店經理的一切都不是很好。如果您在使用它了很多,你甚至可以把它變成一個類

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 
} 

我會做這樣的事情。

2

如果你有一個問題,因爲不顯示/刷新正確組合框時,商店需要太長的時間來加載,該解決方案是創建每家商店是在組合框中使用這樣

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

組合框檢查它們在加載時用於刷新信息的存儲中的參數,但有時組合框甚至在商店開始加載並將「加載」標誌設置爲true之前創建並刷新,然後它當商店完成加載時不會刷新其價值。 將其設置爲true可明確修復問題。 我不知道這是你的情況,但我想我會提到它的情況下。

+0

由於我們的ViewModel是以「異步任務」(Asp.Net MVC)和組合框的形式返回的試圖在他們的商店被加載之前設置他們的價值。設置'loading:true'完全解決了這個問題。 – mdisibio

+0

這節省了我大量的時間/代碼。我們有相同的組合框存儲「種族」條件,在組合框裝載其存儲之前發生表單綁定。我發現這個線程認爲我將不得不編寫客戶代碼來等待所有商店加載,然後再繼續我的form.loadRecord操作。這個簡單的商店配置解決了問題。非常感謝! –

1

使用靈巧JS

靈巧JS是經由扶養噴射中噴射出一個插件。它允許用戶在AJAX調用中添加承諾,只有在調用完成後才能解決承諾。 Link for Deft JS。 使用Ext.defer.All();加載所有5個商店,一旦加載所有商店,將調用特定的回調函數。在這個功能中,實現你的邏輯。

1

ExtJs Store有方法load和load方法有回調函數。

我創建了一個演示。你可以在這裏查詢Sencha fiddle

這個函數會創建存儲並返回。

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