Knockout.js - 在可观察范围内可观察到

时间:2014-06-04 21:24:38

标签: javascript knockout.js

搜索了所有的stackoverflow&其他来源 - 似乎无法找到任何帮助。

我有一个统计表式的UI,带有数据驱动的内容。数据是在后端序列化的巨大数组/对象。

然后我提取该数组中的值 - 它们被设置为observables - 并在具有数据绑定属性的页面上输出它们。

该表格显示指定类别中的效果最佳艺术家以及下方的两位相关艺术家。

问题是我们需要动态更改data-bind属性,以便能够查看数据中的变量属性。

例如,如果用户按“艺术家”过滤,我们要显示艺术家姓名(即

<span data-bind="text: ArtistName()"></span>

BUT

如果用户按“类型”过滤,我们希望HTML的相同部分能够显示跟踪长度(或任何其他任意可观察属性)(即)

最终,我希望有一个可变的数据绑定属性,比如

我知道我可以使用一个可能很大的if语句实现这一点,如下所示:

<!-- ko if: $parent.SortMethod() == 'Topic1' -->
<span data-bind="text: Topic1()"></span>
<!-- /ko -->
<!-- ko if: $parent.SortMethod() == 'Topic2' -->
<span data-bind="text: Topic2()"></span>
<!-- /ko -->
<!-- ko if: $parent.SortMethod() == 'Topic3' -->
<span data-bind="text: Topic3()"></span>
<!-- /ko -->

...等

当然有一种更有效的方式......?

1 个答案:

答案 0 :(得分:2)

您必须将网格数据绑定到一个函数,然后该函数将返回由所需字段排序/过滤的数据。此外,您必须将该下拉列表绑定到视图模型中的observable。

function GridModel(data)
{
      var self = this;
      self.RawData = data;
      self.SortedBy = ko.observable();

      self.GetGridData = function()
      {
           var ret = self.RawData();
           var sortingFld = self.SortedBy();

           if (sortingFld)
           {
               ret = ret.sort(function (a, b) {
                   a = ko.unwrap(a[sortingFld]);
                   b = ko.unwrap(b[sortingFld]);

                   return (a == b ? 0 : a < b ? -1 : 1) * 1;
                   });
           }

           return ret;
      }
}

HTML:

<table class="grid">
    <thead>
        <th>Category</th>
        <th>Artist</th>
        <th>Track</th>
    </thead>

    <tbody data-bind="foreach: GetGridData()">
        <td data-bind="text: Category"></td>
        <td data-bind="text: Artist"></td>
        <td data-bind="text: Track"></td>
    </tbody>
</table>

下拉列表将能够更改SortedBy可观察量并相应地自动刷新网格:

<select data-bind="value: SortedBy, options: ['Artist', 'Track']"></select>

(上面的代码仅演示了升序排序,但您也可以轻松扩展它以进行过滤。)