2

我正在开发 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 - 我只想将数据绑定到视图并使用特定模板显示它。我肯定不想从后面的视图代码动态创建表。

4

1 回答 1

3

如果您的目标是呈现表格,则 ListView 不是您想要的。关键是将集合的概念(您的数据源)与您用来呈现它的控件分开。这就是为什么有一个 WinJS.Binding.List 集合类和一个 WinJS.UI.ListView 控件作为独立实体的原因。

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

虽然您可以将 ListView 声明为表的子表,但它也不会在那里工作,因为 ListView 在您声明它的元素下方创建了一个深层 div 结构。

因此,为此目的计算 ListView。相反,您需要的是一个简单的自定义控件,它可以采用 WinJS.Binding.List 并将模板呈现为该控件的直接子级。在 Windows 8.1 Preview 中,有一个名为 Repeater 的新控件可用于此目的,HTML Repeater 控件示例在 <table> 的上下文中演示了它。请注意,您需要为标题使用 <thead> 并在 <tbody> 上声明控件,以便它可以呈现以 <tr> 作为根元素的模板的副本。

如果您的目标是 Windows 8,那么您当然不会拥有 Repeater,但创建自己的 Repeater 并不太复杂(如果您愿意,可以从 Win8.1 Repeater 源中借用)。使用 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>

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

于 2013-07-30T16:33:31.757 回答