如何在转发器中动态绑定WinJS列表视图

时间:2014-10-14 22:23:15

标签: javascript windows-8 winjs

我有一个使用模板的WinJS中继器。该模板包含WinJS列表视图。我似乎无法弄清楚如何使用 data-win-bind 来设置内部列表视图 itemDataSource

我的中继器:

<section id="genreView" aria-label="Main content" role="main">
    <div id="genreWrapper">
        <div id="genreRows" data-win-control="WinJS.UI.Repeater"
             data-win-options="{template: select('#genreRowTemplate')}">
        </div>
    </div>
</section>

我的模板包含列表视图:

<div id="genreRowTemplate" data-win-control="WinJS.Binding.Template">
    <div id="genreRow">
        <h2 class="genreTitle" data-win-bind="innerText: genreTitle"></h2>
        <div class="genreMovieListView"
                data-win-control="WinJS.UI.ListView"
                data-win-bind="itemDataSource : data"
                data-win-options="{ layout: { type: WinJS.UI.GridLayout },
            itemsDraggable: false,
            selectionMode: 'single',
            tapBehavior: 'none',
            swipeBehavior: 'none',
            itemsReorderable: false,
            itemTemplate: select('#genreMovieTemplate')}">
        </div>
    </div>
</div>

我的列表视图模板:

<div id="genreMovieTemplate" data-win-control="WinJS.Binding.Template">
    <div class="genreMovieItem">
        <img style="width: 175px; height: 250px;" data-win-bind="alt: title; src: posterUrl" />
    </div>
</div>

转发器的数据与此类似(只是它的绑定列表):

var repeaterData = [{genreTitle: "titleA", data: new WinJS.Binding.List() },
{genreTitle: "titleB", data: new WinJS.Binding.List() }
{genreTitle: "titleC", data: new WinJS.Binding.List() }
{genreTitle: "titleD", data: new WinJS.Binding.List() }];

数据是动态创建的,每个绑定列表实际上是更多的数据,因此我无法获得真实数据的良好样本。

我所得到的是一个重复的控制,重复的次数与我的绑定列表中的记录完全重复。我没有得到的是显示的绑定列表。我的内部绑定列表没有通过data-win-bind获取数据绑定。我尝试了一些事情,但我得到的一切都没有或者是错误的。任何帮助表示赞赏。感谢。

编辑:认为绑定的正确方法是data-win-bind =“data-win-options.itemDataSource:data”,但这样做会抛出以下令人困惑的错误:“JavaScript运行时错误:WinJS.UI.Repeater.AsynchronousRender:顶级项目必须同步呈现”。

2 个答案:

答案 0 :(得分:1)

我能够解决我的问题,但我不认为我以正确的方式解决了这个问题。我继续设置转发器的数据源,从上面给我我的genreRows。这总是有效,它只是孩子dataSource我无法弄清楚如何到达。我的解决方案...在加载后在代码中设置它。没有什么花哨的,只是一个对我来说有点讨厌的解决方案。这是我的代码,以防其他人解决这个问题。

 var titleList = $(".genreRow > .genreTitle");
    var genreLists = $(".genreRow > .genreMovieListView");
    for (var i = 0; i < genreLists.length; i++) {
        var title = titleList[i].innerText;
        var listControl = genreLists[i].winControl;

        tempData.forEach(function (element, i) {
            if (element.genreTitle == title)
                listControl.itemDataSource = element.data.dataSource;
        });
    };

基本上上面的代码假设标题是唯一的(它是)。所以它使用它作为遍历数据的关键并以这种方式设置itemDataSource。

我不会将此标记为已接受的答案,以防万一有人可以指出如何“正确”执行此操作。

答案 1 :(得分:1)

老问题,但仍然值得一个好的答案:

我修改了您的HTML以显示正确的绑定语法。

<div id="genreRowTemplate" data-win-control="WinJS.Binding.Template">
<div id="genreRow">
    <h2 class="genreTitle" data-win-bind="innerText: genreTitle"></h2>
    <div class="genreMovieListView"
            data-win-control="WinJS.UI.ListView"
            data-win-bind="winControl.itemDataSource : data.dataSource"
            data-win-options="{ layout: { type: WinJS.UI.GridLayout },
        itemsDraggable: false,
        selectionMode: 'single',
        tapBehavior: 'none',
        swipeBehavior: 'none',
        itemsReorderable: false,
        itemTemplate: select('#genreMovieTemplate')}">
    </div>
</div>

注意winControl.itemDataSourcedata.dataSource。任何不是标准HTML元素属性的WinJS控件属性都需要在数据绑定属性前面的winControl属性。因此onclick元素的button属性并不需要它,但WinJS.UI.Commandicon不在基础button上,所以需要winControl前缀。

此外,ListView控件绑定到WinJS.Binding.List的dataSource属性,而不是List本身。出于某种原因,转发器会绑定到ListView本身。