Knockout.js 使用映射插件在嵌套数组中计算可观测值

Knockout.js 使用映射插件在嵌套数组中计算可观测值,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,我有一张有很多问题的表格。每个问题都有许多答案。在形式层面,我想创建一些计算的观察值,比如总分和问题数量。 formmodel、questionsmodel和answermodel的创建方式相同。 问题模型“知道”答案。它让我可以创建计算出的观察值,比如答案的数量或最大点数 我的问题是表单模型无法识别问题数组。我可以计算每个问题的答案数量,但不能计算表格中的问题数量。我的模型有问题吗?或者我应该调查我的数据吗 function formViewModel(data) { var

我有一张有很多问题的表格。每个问题都有许多答案。在形式层面,我想创建一些计算的观察值,比如总分和问题数量。 formmodel、questionsmodel和answermodel的创建方式相同。 问题模型“知道”答案。它让我可以创建计算出的观察值,比如答案的数量或最大点数

我的问题是表单模型无法识别问题数组。我可以计算每个问题的答案数量,但不能计算表格中的问题数量。我的模型有问题吗?或者我应该调查我的数据吗

function formViewModel(data) {
        var self = this;
        var mapping = {
            'questions': {
                create: function (options) {
                    return new questionsViewModel(options.data);
                }
            }
        };        
        var model = ko.mapping.fromJSON(data, mapping, self);
        model.numberOfQuestions = ko.computed(function () {
            return self.questions().length; // error: self.questions() is not a function
        });
        return model;
    }

    function questionsViewModel(data) {
        var self = this;
        var mapping = {
            'answers': {
                create: function (options) {
                    return new answersViewModel(options.data);
                }
            }
        };
        var model = ko.mapping.fromJS(data, mapping, self);
        model.numberOfAnswers = ko.computed(function () {
            return self.answers().length; // no problem
        });
        return model;
    }

    function answersViewModel(data) {
        var self = this;
        var mapping = {};
        var model = ko.mapping.fromJS(data, mapping, self);
        return model;
    }

我认为您正在尝试在问题完全实例化之前获得问题的长度-您是否可以尝试将您的计算更改为以下内容-

model.numberOfQuestions = ko.computed(function () {
    if (!self.questions()) {return 0;}
    return self.questions().length; // error: self.questions() is not a function
});
但看起来你可能有一些范围问题-

function formViewModel(data) {
    var self = this;
    self.mapping = {
         // do stuff
    };
}
有关在嵌套映射中正确建立作用域的更多信息,请查看此答案。我敢打赌,如果你在你的self.questions()之前先console.log(self)。length它不是你想要的,或者至少现在还不是


谢谢您的建议。然而,它并没有解决我的问题:检查self.questions()仍然给出相同的错误“questions()不是函数”。将函数“formViewModel(数据){”更改为“var formViewModel=函数(数据){”没有做任何事情。我在一个Ajax调用中获得了所有数据。因此formViewModel使用了ko.mapping.fromJSON。问题模型使用的是ko.mappingfromJS。似乎这些函数并不等价……你是对的!!这是一个范围问题。我应该是:return self.formulier.questions().length;(“formulier”是我的JSON字符串的第一个或根元素的名称。非常感谢!