2013-03-13 61 views
0

目前我通過網格應用程序模板提供的​​異步加載數據。由於StorageFile類的異步特性,因此在設置全局WinJS名稱空間中的Data之前,groupedItems.js(「集線器」頁面)在ready處理程序中調用_initializeLayout的問題存在。initializeLayout和異步加載

在​​:

fileNames.forEach(function (val, index, arr) { 
    var uri = new Windows.Foundation.Uri('ms-appx:///data/' + val + '.geojson'); 

    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) { 

     Windows.Storage.FileIO.readTextAsync(file).then(function (contents) { 

      // ... read, parse, and organize the data ... 

      // Put the data into the global namespace 
      WinJS.Namespace.define("Data", { 
       items: groupedItems, 
       groups: groupedItems.groups, 
       getItemReference: getItemReference, 
       getItemsFromGroup: getItemsFromGroup, 
       resolveGroupReference: resolveGroupReference, 
       resolveItemReference: resolveItemReference 
      }); 
     }); 
    }); 
} 

groupedItems.js

// ... 

// This function updates the ListView with new layouts 
    _initializeLayout: function (listView, viewState) { 
     /// <param name="listView" value="WinJS.UI.ListView.prototype" /> 

     if (viewState === appViewState.snapped) { 
      listView.itemDataSource = Data.groups.dataSource; 
      listView.groupDataSource = null; 
      listView.layout = new ui.ListLayout(); 
     } else { 
      listView.itemDataSource = Data.items.dataSource; 
      listView.groupDataSource = Data.groups.dataSource; 
      listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" }); 
     } 
    }, 

// .... 

看到,因爲我動不了這個代碼從這個文件進入無極done()功能​​,我怎麼做應用程序要等到Data在初始化佈局之前在WinJS名稱空間中初始化?

回答

0

您有兩個異步操作正在進行(加載數據並加載頁面)和一個操作(初始化網格),只有在兩個異步操作完成後纔會發生(加載頁面,數據可用) 。有很多方法可以解決這個問題,這取決於你想採用哪種架構方法。

  1. 蠻力方法是創建檢查,看看如果這兩個文件已準備就緒,將數據加載一個新的功能,如果有的話,它調用_initializeLayout()。然後在兩個地方(文檔加載的位置和數據可用的時間)調用該函數,並且只有在兩個條件都滿足時纔會執行該函數。看起來您可以通過檢查是否存在全局的Data項目及其相關屬性來判斷數據是否已加載。

  2. 還有更多的解決方案在結構上稍微更簡潔。例如,在您的文檔就緒處理程序中,您可以檢查數據是否可用。如果是,則只需初始化佈局。如果您沒有安裝通知,那麼當數據可用時,您的回調將被調用,然後您可以初始化佈局。如果數據加載代碼當前沒有通知方案,那麼您創建一個可供任何想要在數據加載時調用的客戶端使用的代碼。這比第一種方法的優勢在於數據加載代碼不必知道任何有關網格的內容。網格必須知道數據 - 這是合理的,因爲網格需要數據。

  3. 雖然我個人並不熟悉承諾/完成系統,但確實有辦法使用承諾/完成系統來建議使用該方法的好方法。

+0

你可以擴展一下「創建通知」方案來執行回調函數,或者提供一些這方面的例子嗎? – 2013-03-13 20:58:11

+0

在'data.js'中,可以添加一個名爲'notifyWhenDataReady(fn)'的函數,該函數將回調函數作爲參數。然後,當data.js中的數據準備就緒時,它會調用該回調函數(如果已註冊的話)。在groupedItems中,它會檢查數據是否已經可用。如果沒有,它會安裝回調函數並推遲調用'_initializeLayout()'直到調用回調函數。這樣,'data.js'不必具體瞭解'_initializeLayout()'或'groupedItems.js'的任何內容,但它仍然可以在需要時向其他模塊提供正確的信息。 – jfriend00 2013-03-13 21:11:36

+0

我遇到的唯一問題是'noficyWh​​enDataReady(fn)'的作用域限於'data.js',所以我該如何傳遞迴調函數參數fn? – 2013-03-13 23:45:38