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

Posted

技术标签:

【中文标题】淘汰赛无法使用函数代替 ko.computed()【英文标题】:Knockout unable to use function instead of ko.computed() 【发布时间】:2019-06-18 15:50:00 【问题描述】:

我有一个 UI,它显示了一个剔除绑定复选框和一个 html 表格。根据复选框的设置和每行中记录的某些属性的值,我想隐藏某些行。

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

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

当然我还有一个复选框,isOnlyFufillmentChecked

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

我最初想通过将 showRowBasedOnFulfillmentCriteria() 设置为 ko.computed 来解决此问题,但有一个问题。复选框(可观察)的值只是确定行可见性所需条件的 一个。其他标准在我构建表时发生变化,循环记录。

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

当我说一个函数不工作时,我的意思是我已经把它剥离为最基础的、可验证的例子。从我的视图模型来看,这里是 showRowBasedOnFulfillmentCriteria() 写成 ko.computed

       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 隐藏行; return true 显示它们。但是当我尝试将其作为一个函数时会发生以下情况:

       self.showRowBasedOnFulfillmentCriteria = function () 
       return false;    
    ;

这里,写成一个函数,即使总是返回 false,所有行都显示。换句话说,函数的返回值似乎没有任何关系。在我充实函数的真实代码之前,我需要知道我可以用它来替换 ko.computed。

[编辑:使用 Chrome 的调试器,在函数中设置断点,似乎该函数甚至从未被调用;当我将 FUNCTION 绑定到敲除中的可见属性时,标记似乎总是假定 TRUE 的值。请继续阅读...]

我是否误解了 ko.computed 可以轻松替换为函数的说法?

该函数与绑定到复选框的 observable 和(未注释掉时)在同一视图模型中定义,ko.computed 版本可以代替该函数并确实有效。

如果我还没有写太多,我对函数的最终目标是:

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

TR 绑定看起来像这样:

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

【问题讨论】:

您可以将一个函数传递给 ko.computed,但只需在那里检查您的 observables。这种做你正在寻找的东西吗? jsfiddle.net/b8wxz72o/1 谢谢蒂姆。我的两个参数虽然不是可观察的。它们是在我构建 tbody 时通过使用 foreach 迭代而派生的对象的成员。有趣的是,我可以将一个函数传递给一个计算函数。也许我可以设计一种方法来传递我的函数,该函数采用不可观察值并将 IT 传递给计算?我会试一试并报告。我主要担心的是,由于某种原因,我在视图模型中编写的函数 似乎 无法识别(由于它返回 false,这些行仍然显示 :-( ) 这应该可以通过computed 实现。你能创建一个 minimal sn-p 或 fiddle 你的 HTML 和视图模型吗?基本上,我想看看表格是如何形成的,哪些属性应该用作标志。目前尚不清楚您是要在每个行对象中还是在父视图模型中使用showRowBasedOnFulfillmentCriteria 【参考方案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/

【讨论】:

你的 jsfiddle 是纯金的 Woodrow 兄弟。我正在使用它向后工作,看看我自己对函数的使用哪里出错了。

以上是关于淘汰赛无法使用函数代替 ko.computed()的主要内容,如果未能解决你的问题,请参考以下文章

UI未使用ko.utils.arrayFilter进行更新

在 knout.js 中遍历 observablearray 时,如何检索 foreach 的 ko.computed 运行总和

淘汰:为什么我的计算函数会自动将项目推送到我的可观察数组中?

用淘汰赛过滤谷歌标记

计算选定的表值(淘汰赛,Javascript)

使用knockoutjs在文本框“keydown”之后过滤的显示列表