WinJS ListView中的特殊JSON绑定

时间:2014-01-16 20:51:34

标签: json windows-store-apps windows-8.1

我在将此JSON绑定到列表视图时遇到问题。 http://pubapi.cryptsy.com/api.php?method=marketdatav2

没有数据显示。

Data.js

(function () {
    "use strict";

    var _list;

    WinJS.xhr({ url: 'http://pubapi.cryptsy.com/api.php?method=marketdatav2' }).then(
        function (response) {
            var json = JSON.parse(response.responseText);
            _list = new WinJS.Binding.List(json.return.markets);
        },
        function (error) {
            //handle error 
        }
    );

    var publicMembers =
        {
            itemList: _list
        };

    WinJS.Namespace.define("DataExample", publicMembers);
})();

HTML:

<section aria-label="Main content" role="main">
            <div id="listItemTemplate" data-win-control="WinJS.Binding.Template">
                <div class="listItem">
                    <div class="listItemTemplate-Detail">
                        <h4 data-win-bind="innerText: label"></h4>
                    </div>
                </div>
            </div>
            <div id="listView" data-win-control="WinJS.UI.ListView" data-win-options="{itemDataSource : DataExample.itemList, itemTemplate: select('#listItemTemplate'), layout: {type: WinJS.UI.GridLayout}}"></div>
</section>

我觉得API不是很好。 这部分有点奇怪吗?

  

“市场”:{ “ADT / XPM”:{...} ...}

1 个答案:

答案 0 :(得分:1)

您的代码中有三件事情在这里发生。

首先,ListView必须绑定到WinJS.Binding.List的dataSource属性,而不是直接绑定到List。因此,在您的HTML中,您可以使用itemDataSource:DataExample.itemList.dataSource,或者您可以使DataExample.itemList取消引用该级别的dataSource。

其次,您还遇到了在DataExample.itemList甚至填充之前,data-win-options中的itemDataSource的声明性绑定发生的问题。在ListView实例化时,_list和itemList将是未定义的。这会导致尝试取消引用.dataSource时出现问题。

解决这个问题的方法是确保在启动时至少使用WinJS.Binding.List的空实例初始化DataExample.itemList。所以把这个和第一点放在一起,我们有这个:

var _list = new WinJS.Binding.List();

var publicMembers =
    {
        itemList: _list.dataSource
    };

有了这个,你可以稍后用另一个List实例替换_list,ListView将刷新自己。

这将我们带到第三个问题,用您的HTTP响应数据填充List。 WinJS.Binding.List在其构造函数中使用数组,而不是对象。您直接从HTTP请求传递解析的JSON对象,这将无法正常工作。

现在,如果您已经像以前一样在_list中有一个WinJS.Binding.List实例,那么您可以直接遍历该对象并将项目直接添加到List中,如下所示:

var jm = json.return.markets;

for (var i in jm) {                
    _list.push(jm[i]);     
}

或者,您可以填充单独的数组,然后从中创建一个新的List。但是,在这种情况下,您需要在代码中将新的List.dataSource分配给ListView:

var jm = json.return.markets;            
var markets = [];

for (var i in jm) {                
    markets.push(jm[i]);
}

_list = new WinJS.Binding.List(markets);

var listview = document.getElementById("listView").winControl;
listview.itemDataSource = _list.dataSource;

两种方式都有效(我测试了它们)。虽然第一个解决方案更简单,但是如果您发出另一个HTTP请求并从中重新填充,则需要确保清除列表。使用第二个解决方案,您只需为每个请求创建一个新列表,并将其交给ListView,这可能会根据您的特定需求更好地工作。

另请注意,在第二个解决方案中,您可以完全从HTML中删除itemDataSource选项,还可以消除DataExample命名空间及其变量,因为您每次都会在代码中分配数据源。然后,您还可以将_list完全保留在本地HTTP请求中。

希望有所帮助。如果您想了解有关ListView复杂性的更多信息,请参阅我的免费电子书第7章,来自MSPress,Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition