淘汰赛无法使用函数代替ko.computed()

时间:2019-01-24 20:12:59

标签: knockout.js

我有一个UI,该UI显示一个绑定边界的复选框和一个HTML表。根据复选框的设置和每行记录 中某些记录的某些属性的值,我要隐藏某些行。

我通过在TR上使用敲除的可见绑定解决了这个问题:

<tr data-bind="visible: $root.showRowBasedOnFulfillmentCriteria">

当然还有一个复选框, isOnlyFufillmentChecked

<input type="checkbox" data-bind="checked: $root.isOnlyFulfillmentChecked, click: $root.productsRefresh" />

我首先想到要通过将 showRowBasedOnFulfillmentCriteria()设为ko.compute来解决此问题,但是存在一个问题。复选框的值(可观察的)仅是确定行可见性所需条件的 一个 。当我建立表并遍历记录时,其他条件也会改变。

我的理解是您不能将参数传递给ko.computeds。在研究StackOverflow上的问题时,每个人似乎都说我可以轻松地使用放置在视图模型中的函数,而不是计算函数。但是,功能不起作用。

当我说一个功能不起作用时,我的意思是我已将此剥离为最基础,可验证的示例。在我看来,这是 showRowBasedOnFulfillmentCriteria()写为 ko.computing

       self.showRowBasedOnFulfillmentCriteria = ko.computed(function () {
       return false;   // false will hide the rows, true will show them.  the computed() is "known" to the markup
   }, this);

如您所见,我采用了一种非常简单的方法,只是返回一个布尔值,以查看是否可以控制计算所得行的可见性。返回false隐藏行。返回true显示它们。但是,当我尝试将其用作功能时,会发生以下情况:

       self.showRowBasedOnFulfillmentCriteria = function () {
       return false;    
    };

这里,尽管总是返回false,但仍以函数形式编写,所有行都会显示。换句话说,函数的返回值似乎没有任何影响。在充实该函数的真实代码之前,我需要知道可以使用它代替ko.computed。

[编辑:使用Chrome的调试器,在函数中设置一个断点,看来该函数从未被调用过;当我将FUNCTION绑定到挖空中的visible属性时,标记似乎总是假定TRUE的值。请继续阅读...]

我是否误解了ko.compute可以很容易地被函数替换的说法?

该函数与复选框的可观察范围以及(当未注释掉时)可在其中起作用并且可以工作的ko.computing版本在同一视图模型中定义。

如果我还没写太多,那么该函数的最终目标是:

self.showRowBasedOnFulfillmentCriteria = function (flag1, flag2) {
       return self.isOnlyFufillmentChecked && flag1 && flag2;    
    };

TR绑定看起来像这样:

<tr data-bind="visible: $root.showRowBasedOnFulfillmentCriteria(Criteria1, Criteria2)">

1 个答案:

答案 0 :(得分:1)

您绝对可以做到这一点。只需在视图模型上创建一个函数,然后将其输出传递到visible绑定即可。您可以将当前行作为参数以及视图模型上的引用属性作为参数传递。

示例代码:

function ViewModel() {
  var vm = this;

  vm.hideNoFooRows = ko.observable(false);
  vm.row = ko.observableArray([
    { foo: true, val: 'Row 1' },
    { foo: false, val: 'Row 2' },
    { foo: true, val: 'Row 3' },
    { foo: false, val: 'Row 4' },
    { foo: true, val: 'Row 5' }
  ]);

  vm.isVisible = isVisible;

  function isVisible(row) {
    let hide = ko.unwrap(vm.hideNoFooRows);
    return hide ? row.foo : !hide;
  }
}

ko.applyBindings(new ViewModel());

HTML:

<table border="1" style="width: 50%">
  <tbody data-bind="foreach: row">
    <tr data-bind="visible: $parent.isVisible($data)">
      <td data-bind="text: val"></td>
      <td data-bind="text: foo"></td>
    </tr>
  </tbody>
</table>

JSFiddle:https://jsfiddle.net/thebluenile/cjmd1hp0/