Knockout.js:计算的可观察值未按预期更新
Knockout.js: computed observable not updating as expected
编辑: 为函数 populateDropdown 和函数 isSystemCorrect 添加了代码(见底部)
编辑 2 我已经缩小了范围,问题似乎出现在计算可观察对象的 arrayFilter 函数中。这 returns 一个空数组,无论我尝试什么。我已经检查 self.testsuites() 在过滤之前看起来没问题,但过滤仍然失败。
我的计算可观察、过滤测试套件有问题。
正如您从屏幕转储中看到的那样,测试套件可观察值已正确填充,但计算出的可观察值仍为空。我还尝试从下拉菜单中选择除 "Payment" 之外的另一个选项,以查看这是否会触发 observable,但没有。
我认为每次 self.testsuites() 或 self.dropdownSelected() 更改时计算的可观察值都会更新,但它似乎不会触发它们。
我在这里做错了什么?
我只是想让计算的可观察对象在所选下拉选项之后过滤测试套件,每次它们中的任何一个发生变化时。
function ViewModel() {
var self = this;
// The item currently selected from a dropdown menu
self.dropdownSelected = ko.observable("Payment");
// This will contain all testsuites from all dropdown options
self.testsuites = ko.mapping.fromJS('');
// This will contain only testsuites from the chosen dropdown option
self.filteredTestsuites = ko.computed(function () {
return ko.utils.arrayFilter(self.testsuites(), function (testsuite) {
return (isSystemCorrect(testsuite.System(), self.dropdownSelected()));
});
}, self);
// Function for populating the testsuites observableArray
self.cacheTestsuites = function (data) {
self.testsuites(ko.mapping.fromJS(data));
};
self.populateDropdown = function(testsuiteArray) {
for (var i = 0, len = testsuiteArray().length; i < len; ++i) {
var firstNodeInSystem = testsuiteArray()[i].System().split("/")[0];
var allreadyExists = ko.utils.arrayFirst(self.dropdownOptions(), function(option) {
return (option.Name === firstNodeInSystem);
});
if (!allreadyExists) {
self.dropdownOptions.push({ Name: firstNodeInSystem });
}
}
};
}
$(document).ready(function () {
$.getJSON("/api/TestSuites", function (data) {
vm.cacheTestsuites(data);
vm.populateDropdown(vm.testsuites());
ko.applyBindings(vm);
});
}
函数是系统正确的:
function isSystemCorrect(system, partialSystem) {
// Check if partialSystem is contained within system. Must be at beginning of system and go
// on to the end or until a "/" character.
return ((system.indexOf(partialSystem) == 0) && (((system[partialSystem.length] == "/")) || (system[partialSystem.length] == null)));
}
按照评论中的建议 - 重写 cacheTestsuites 方法:
self.testsuites = ko.observableArray();
self.filteredTestsuites = ko.computed(function () {
return ko.utils.arrayFilter(self.testsuites(), function (testsuite) {
return (isSystemCorrect(testsuite.System(), self.dropdownSelected()));
});
});
self.cacheTestsuites = function (data) {
var a = ko.mapping.fromJS(data);
self.testsuites(a());
};
这里唯一不同的是从映射函数解包 observableArray。
编辑: 为函数 populateDropdown 和函数 isSystemCorrect 添加了代码(见底部)
编辑 2 我已经缩小了范围,问题似乎出现在计算可观察对象的 arrayFilter 函数中。这 returns 一个空数组,无论我尝试什么。我已经检查 self.testsuites() 在过滤之前看起来没问题,但过滤仍然失败。
我的计算可观察、过滤测试套件有问题。
正如您从屏幕转储中看到的那样,测试套件可观察值已正确填充,但计算出的可观察值仍为空。我还尝试从下拉菜单中选择除 "Payment" 之外的另一个选项,以查看这是否会触发 observable,但没有。
我认为每次 self.testsuites() 或 self.dropdownSelected() 更改时计算的可观察值都会更新,但它似乎不会触发它们。
我在这里做错了什么?
我只是想让计算的可观察对象在所选下拉选项之后过滤测试套件,每次它们中的任何一个发生变化时。
function ViewModel() {
var self = this;
// The item currently selected from a dropdown menu
self.dropdownSelected = ko.observable("Payment");
// This will contain all testsuites from all dropdown options
self.testsuites = ko.mapping.fromJS('');
// This will contain only testsuites from the chosen dropdown option
self.filteredTestsuites = ko.computed(function () {
return ko.utils.arrayFilter(self.testsuites(), function (testsuite) {
return (isSystemCorrect(testsuite.System(), self.dropdownSelected()));
});
}, self);
// Function for populating the testsuites observableArray
self.cacheTestsuites = function (data) {
self.testsuites(ko.mapping.fromJS(data));
};
self.populateDropdown = function(testsuiteArray) {
for (var i = 0, len = testsuiteArray().length; i < len; ++i) {
var firstNodeInSystem = testsuiteArray()[i].System().split("/")[0];
var allreadyExists = ko.utils.arrayFirst(self.dropdownOptions(), function(option) {
return (option.Name === firstNodeInSystem);
});
if (!allreadyExists) {
self.dropdownOptions.push({ Name: firstNodeInSystem });
}
}
};
}
$(document).ready(function () {
$.getJSON("/api/TestSuites", function (data) {
vm.cacheTestsuites(data);
vm.populateDropdown(vm.testsuites());
ko.applyBindings(vm);
});
}
函数是系统正确的:
function isSystemCorrect(system, partialSystem) {
// Check if partialSystem is contained within system. Must be at beginning of system and go
// on to the end or until a "/" character.
return ((system.indexOf(partialSystem) == 0) && (((system[partialSystem.length] == "/")) || (system[partialSystem.length] == null)));
}
按照评论中的建议 - 重写 cacheTestsuites 方法:
self.testsuites = ko.observableArray();
self.filteredTestsuites = ko.computed(function () {
return ko.utils.arrayFilter(self.testsuites(), function (testsuite) {
return (isSystemCorrect(testsuite.System(), self.dropdownSelected()));
});
});
self.cacheTestsuites = function (data) {
var a = ko.mapping.fromJS(data);
self.testsuites(a());
};
这里唯一不同的是从映射函数解包 observableArray。