Knockout计算过滤器上的新值

Knockout compute new values on filter

本文关键字:新值 过滤器 计算 Knockout      更新时间:2023-09-26

我正在构建一个数字量很大的应用程序,该应用程序的一个功能是能够在最后的三个结果之间进行筛选。这些是:药物,疾病和;全部(两者)。

我是Knockout的新手,所以不完全确定处理以下情况的最佳实践方法是什么。

我有值过滤,我的问题在于计算新值底部的总数必须反映表中当前可见的数据尽管下面代码笔中的这些单元格值(除了总数)是静态的,但它们在我的应用程序中实际上是动态的,它们是存储在前几页应用程序的sessionStorage中的几个值的计算组合。(此屏幕为汇总页面)。

示例:

self.total = ko.computed(function () { return sessionStorage.getItem('1') * sessionStorage.getItem('2') });

所以澄清一下;最初,表底部计算的总数是表单元格中数字的总和,这些数字是sessionStorage中数字的乘积。然后,每次过滤表以反映可见数据的总和时,都需要更新总值。

http://codepen.io/anon/pen/nlemE

我很感激这可能很复杂,如果我解释得不够好,请告诉我,我会澄清的。

与其使用jQuery来隐藏/显示行,不如使用observableArray来存储值,并使用计算函数在每次筛选器值更改时对该数组进行筛选。

下面是一个更新的CodePen,展示了它的工作原理:http://codepen.io/anon/pen/HAzcf?editors=101

您的数据代码将是一个对象数组,而不是r1c1、r2c1等。我们还添加了一个筛选字段,这样我们就不必将其硬编码到HTML中。

self.values = ko.observableArray([
  {
    c1: ko.observable(10),
    c2: ko.observable(32),
    c3: ko.observable(36),
    filter: ko.observable('drugs')
  },
  {
    c1: ko.observable(70),
    c2: ko.observable(46),
    c3: ko.observable(31),
    filter: ko.observable('disease')
  }
  // etc..
]);

我们的切换功能现在只需更新一个可观察到的:

// toggle
self.filter = ko.observable('all');
self.toggleVis = function (data, event) {
    self.filter(event.target.value);
};

每次更新self.filter可观测值时,过滤值都会更新:

self.filteredValues = ko.computed(function() {
    var filter = self.filter();
    return ko.utils.arrayFilter(self.values(), function(item) {
        return filter == 'all' || item.filter() == filter;
    }); 
});

每当filteredValues发生更改时,我们的合计属性都会更新:

self.total1 = ko.computed(function () {
    var total = 0,
        values = self.filteredValues();
    for(var i = 0; i < values.length; i++) {
        total += values[i].c1();
    }
    return total;
});

您的HTML表代码也变得简单,只需在过滤后的可观察数组上进行迭代:

<table>
  <tbody>
    <!-- ko foreach: filteredValues -->
    <tr class="row">
      <td data-bind="text:c1"></td>
      <td data-bind="text:c2"></td>
      <td data-bind="text:c3"></td>
    </tr>
    <!-- /ko -->
    <tr class="totals">
      <td data-bind="text:total1"></td>
      <td data-bind="text:total2"></td>
      <td data-bind="text:total3"></td>
    </tr>
  </tbody>
</table>

您希望对每个可观察器使用Knockout Subscription。

self.r1c1().subscribe(function(newValue) {
    // update the sum
});

然而,您可能不想添加20个订阅,而是想使用Knockout Observable Array来存储/更新您的单个值。

var myObservableArray = ko.observableArray();    
myObservableArray.push(<value for row 1>);
myObservableArray.push(<value for row 2>);
// etc

然后,您可以为三个专栏中的每一个订阅一次。

self.myObservableArray.subscribe(function(newValue) {
    // re-calculate the sum of the values
});