【问题标题】:Knockout.js: computed observable not updating as expectedKnockout.js:计算出的 observable 没有按预期更新
【发布时间】:2015-03-11 08:41:53
【问题描述】:

编辑:为函数 populateDropdown 和函数 isSystemCorrect 添加代码(见底部)

编辑 2 我已经把它缩小了一点,问题似乎出现在计算的 observable 中的 arrayFilter 函数中。无论我尝试什么,这都会返回一个空数组。我在过滤之前检查了 self.testsuites() 看起来没问题,但过滤仍然失败。

我的计算出的 observable、filteredTestsuites 有问题。

从屏幕转储中可以看出,testsuites observable 已正确填充,但计算出的 observable 仍为空。我还尝试从下拉菜单中选择“付款”以外的其他选项,看看这是否会触发可观察对象,但没有。

我认为每次 self.testsuites() 或 self.dropdownSelected() 更改时计算的 observable 都会更新,但似乎都不会触发它们。

我在这里做错了什么?

我只是想让计算的 observable 过滤器在选择的下拉选项之后成为测试套件,每次它们中的任何一个发生变化时。

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);
    });
}

函数isSystemCorrect:

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)));
}

【问题讨论】:

  • 也许您还应该向我们展示populateDropdownisSystemCorrect,因为那里最有可能出现“错误”。
  • 新增功能:)
  • 我要尝试的第一件事是调用带括号和不带括号的可观察对象。喜欢self.testsuitesself.testsuites()。我见过很多情况,其中将“调用”更改为带有或不带有括号的 observable 已经修复了各种静默错误。
  • 如果我们想要 true 结果,systempartialSystem 参数应该是什么样子?
  • cacheTestsuites 调用包装了testsuites 的内容,导致arrayFilter 的第一个参数不是数组,从而导致您的计算问题。就在过滤 console.log(self.testsuites()) 之前,您会看到问题。

标签: javascript knockout.js knockout-2.0 computed-observable


【解决方案1】:

按照评论中的建议 - 重写 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。

【讨论】:

    猜你喜欢
    • 2014-08-21
    • 2015-08-18
    • 2013-05-16
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    相关资源
    最近更新 更多