WinJS在表中呈现listView

时间:2013-07-30 15:27:23

标签: windows-8 microsoft-metro winjs

我正在研究HTML / JS Win8商店应用。我想在表中呈现ListView。我怎么做到这一点?

现在我有类似的东西:

        <table id="products">
            <tbody>
                <tr>
                    <th>Name</th>
                    <th>Description</th>
                </tr>
                <tr data-win-control="WinJS.Binding.Template" id="productsRowTemplate">
                    <td data-win-bind="textContent: name"></td>
                    <td data-win-bind="textContent: description"></td>
                </tr>
            </tbody>
        </table>

        <div id="productsListView"
            data-win-control="WinJS.UI.ListView"
            data-win-bind="winControl.itemDataSource: products.dataSource;"
            data-win-options="{ 
            itemTemplate: select('#productsRowTemplate'), 
            layout: { type: WinJS.UI.ListLayout }
            }">
        </div>

然而,结果并非我所期望的结果: http://postimg.org/image/4z39tvu9v/

我想达到与此类似的效果(我在视图中使用了该示例中的样式): http://www.w3schools.com/css/tryit.asp?filename=trycss_table_fancy

我使用listView的原因是我正在使用ViewModels,它通过属性公开集合 - 我只想将数据绑定到视图并使用特定模板显示它。我肯定不想从后面的视图代码中动态创建表。

1 个答案:

答案 0 :(得分:3)

如果您的目标是渲染表,则ListView不是您想要的。关键是将集合的想法 - 您的数据源 - 与您用于呈现它的控件分开。这就是为什么WinJS.Binding.List集合类和WinJS.UI.ListView控件作为单独的实体。

表是呈现集合的一种方式; ListView是另一个。因此,尝试将两者结合起来并没有多大意义。在您的标记中,模板元素实际上将从DOM中删除而不在表中呈现。 ListView将尝试使用该模板来呈现自身,但是当它生成&lt; tr&gt;时和&lt; td&gt;它自己的div中的元素(在&lt; table&gt;之外)它不会真正起作用。也就是说,模板会为数据源中的每个项呈现为您声明ListView的div的子项,而不是在您声明模板的位置。

虽然你可以将ListView声明为表的子节点,但它不会在那里工作,因为ListView在你声明它的元素下面创建一个深div结构。

因此,为此目的计算ListView。你想要的是一个简单的自定义控件,可以使用WinJS.Binding.List并将模板呈现为该控件的直接子项。在Windows 8.1预览版中,有一个名为Repeater的新控件可用于此目的,HTML Repeater control sample在&lt; table&gt;的上下文中对其进行演示。请注意,您需要使用&lt; thead&gt;对于你的标题并在&lt; tbody&gt;上声明控件所以它可以渲染具有&lt; tr&gt;的模板的副本作为根元素。

如果你的目标是Windows 8,你当然不会拥有中继器,但是创建你自己的中继器并不是太复杂(如果你愿意,可以从Win8.1中继器源中借用)。使用WinJS.Class.define定义构造函数,并确保您有可以通过其声明性地指定数据源和模板的选项。该模板将包含您的data-win-bind属性。在控件的构造函数中,遍历Binding.List,为列表中的每个项呈现模板的副本。然后使用该项的根元素和数据源中的项调用WinJS.Binding.processAll,这将设置所需的数据绑定。

您将在tbody元素上再次声明此控件,以便在正确的位置创建tr子元素。要使用Repeater示例(它使用内联模板):

<table class="table">
  <thead class="table-header"><tr><td>Id</td><td>Description</td></tr></thead>
    <tbody class="table-body"
      data-win-control="WinJS.UI.Repeater" data-win-options="{data: Data.items}">
      <tr class="table-body-row">
          <td data-win-bind="textContent: id"></td>
          <td data-win-bind="textContent: description"></td>
      </tr>
  </tbody>
</table>

最后,您将动态创建表,但它已封装在控件中,因此您可以声明性地设置数据绑定关系。