Knockout 无法使用函数代替 ko.computed()
Knockout unable to use function instead of ko.computed()
我有一个 UI 显示一个敲除绑定复选框和一个 HTML table。根据复选框的设置和每行记录的某些属性的值,我想隐藏某些行。
我通过在 TR 上使用 knockout 的可见绑定解决了这个问题:
<tr data-bind="visible: $root.showRowBasedOnFulfillmentCriteria">
当然我有一个复选框,isOnlyFufillmentChecked:
<input type="checkbox" data-bind="checked: $root.isOnlyFulfillmentChecked, click: $root.productsRefresh" />
我首先想到通过使 showRowBasedOnFulfillmentCriteria() 成为 ko.computed 来解决这个问题,但是有一个问题。复选框(可观察)的值仅是确定行可见性所需标准的 之一。其他标准在我构建 table 时发生变化,遍历记录。
我的理解是不能给ko.computed传参数。在 Whosebug 上研究这个问题,每个人似乎都在说我可以很容易地使用一个函数,放在我的视图模型中,而不是计算。但是,功能不起作用。
当我说一个函数不起作用时,我的意思是我已经将其剥离到最基本的、可验证的示例。在我的视图模型中,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);
如您所见,我采用了一种非常简单的方法,只是 returning 一个布尔值,看看我是否可以控制来自计算的行的可见性。返回 false 隐藏行; return true 显示它们。但是当我将它作为一个函数来尝试时会发生什么:
self.showRowBasedOnFulfillmentCriteria = function () {
return false;
};
这里,写成一个函数,即使总是 returning false,所有行都显示 。换句话说,函数的 return 值似乎没有任何意义。在充实函数的实际代码之前,我需要知道我可以用它来替换 ko.computed.
[编辑:使用 Chrome 的调试器,在函数中设置断点,似乎函数从未被调用;当我在敲除中将 FUNCTION 绑定到可见的 属性 时,标记似乎总是采用 TRUE 值。请继续阅读...]
我是否误解了 ko.computed 可以很容易地替换为函数的说法?
该函数在与绑定到复选框的可观察对象相同的视图模型中定义(当未注释掉时),ko.computed 版本可以代替该函数并正常工作。
如果我还没有写太多的话,我对该功能的最终目标是:
self.showRowBasedOnFulfillmentCriteria = function (flag1, flag2) {
return self.isOnlyFufillmentChecked && flag1 && flag2;
};
TR 绑定将如下所示:
<tr data-bind="visible: $root.showRowBasedOnFulfillmentCriteria(Criteria1, Criteria2)">
你绝对可以做到。只需在您的视图模型上创建一个函数并将其输出传递给 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>
我有一个 UI 显示一个敲除绑定复选框和一个 HTML table。根据复选框的设置和每行记录的某些属性的值,我想隐藏某些行。
我通过在 TR 上使用 knockout 的可见绑定解决了这个问题:
<tr data-bind="visible: $root.showRowBasedOnFulfillmentCriteria">
当然我有一个复选框,isOnlyFufillmentChecked:
<input type="checkbox" data-bind="checked: $root.isOnlyFulfillmentChecked, click: $root.productsRefresh" />
我首先想到通过使 showRowBasedOnFulfillmentCriteria() 成为 ko.computed 来解决这个问题,但是有一个问题。复选框(可观察)的值仅是确定行可见性所需标准的 之一。其他标准在我构建 table 时发生变化,遍历记录。
我的理解是不能给ko.computed传参数。在 Whosebug 上研究这个问题,每个人似乎都在说我可以很容易地使用一个函数,放在我的视图模型中,而不是计算。但是,功能不起作用。
当我说一个函数不起作用时,我的意思是我已经将其剥离到最基本的、可验证的示例。在我的视图模型中,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);
如您所见,我采用了一种非常简单的方法,只是 returning 一个布尔值,看看我是否可以控制来自计算的行的可见性。返回 false 隐藏行; return true 显示它们。但是当我将它作为一个函数来尝试时会发生什么:
self.showRowBasedOnFulfillmentCriteria = function () {
return false;
};
这里,写成一个函数,即使总是 returning false,所有行都显示 。换句话说,函数的 return 值似乎没有任何意义。在充实函数的实际代码之前,我需要知道我可以用它来替换 ko.computed.
[编辑:使用 Chrome 的调试器,在函数中设置断点,似乎函数从未被调用;当我在敲除中将 FUNCTION 绑定到可见的 属性 时,标记似乎总是采用 TRUE 值。请继续阅读...]
我是否误解了 ko.computed 可以很容易地替换为函数的说法?
该函数在与绑定到复选框的可观察对象相同的视图模型中定义(当未注释掉时),ko.computed 版本可以代替该函数并正常工作。
如果我还没有写太多的话,我对该功能的最终目标是:
self.showRowBasedOnFulfillmentCriteria = function (flag1, flag2) {
return self.isOnlyFufillmentChecked && flag1 && flag2;
};
TR 绑定将如下所示:
<tr data-bind="visible: $root.showRowBasedOnFulfillmentCriteria(Criteria1, Criteria2)">
你绝对可以做到。只需在您的视图模型上创建一个函数并将其输出传递给 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>