2013-03-13 59 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