我试图将computed
对象与options
绑定一起使用,但是computed
仅在文档加载时调用(而不是每次单击按钮时)。但是,当我用简单的函数替换computed
时,它会按预期工作-在每次创建项目时都会调用该函数。
差异的原因是什么?给出here的答案使我认为它们的行为应相同,但显然它们不相同。那为什么?
代码(或fiddle):
var ViewModel = function() {
var self = this;
self.items = ko.observableArray([]);
self.toggler = false;
self.allowedOptions = ["A", "B", "C"];
self.availableOptions = ko.computed(function() {
var allowedOptions = self.allowedOptions.slice();
self.toggler = !self.toggler;
if (self.toggler) {
return allowedOptions.splice(2, 1);
}
return allowedOptions;
});
self.createItems = function () {
self.items.push({});
}
}
vm = new ViewModel()
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
<button data-bind="text: 'create a dropdown', click: createItems"></button>
<div data-bind="foreach: items">
<select data-bind="options: $parent.availableOptions,
optionsText: $data,
value: $data"></select>
</div>
</div>
豪
最佳答案
第一次触发KO computed
,然后在observable
内部的computed
更改的任何时候触发。您的observables
中没有computed
,因此只会在第一次触发。
这是您的示例,经过修改后,通过更改computed
并翻转observable
中的self.toggler()
值,每次单击按钮时都会触发self.createItems()
。
var ViewModel = function() {
var self = this;
self.items = ko.observableArray([]);
self.toggler = ko.observable(false);
self.availableOptions = ko.computed(function() {
if (self.toggler()) {
return ["C"];
}
return ["A", "B", "C"];
});
self.createItems = function() {
self.items.push({});
self.toggler(!self.toggler());
}
}
vm = new ViewModel()
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div>
<button data-bind="text: 'create a dropdown', click: createItems"></button>
<div data-bind="foreach: items">
<select data-bind="options: $parent.availableOptions,
value: $data"></select>
</div>
</div>
更新以更全面地说明
KO缓存
computed
函数的结果,并且直到该observable
函数内部的computed
更改后才重新评估它。