Knockout arrayForEach未定义属性

Knockout arrayForEach undefined property

本文关键字:属性 未定义 arrayForEach Knockout      更新时间:2023-09-26

我很难从一个可观察数组中的每个项目中获得一个数字,并将这些数字加在一起并将其分配给另一个计算变量。这是我现在有的…

Semesters: ko.observableArray([
    {
        semesterName: "Fall",
        semesterCode: "300",
        PlannedCourses: ko.observableArray([]),
        totalCredits: ko.computed(function(){
            var total = 0;
            ko.utils.arrayForEach(this.PlannedCourses, function (course) {
                total += course.MinHours();
            });
            return total;
        }),
    },
    ...

我要做的是,在totalCredits变量中,我试图遍历PlannedCourses数组并获得每个项目的MinHours变量,并将它们一起添加到total变量中。然后将其返回到学期数组中的totalCredits项。我遇到的问题是在ko.utils.arrayForEach部分中获得PlannedCourses变量。我得到了一个未定义,我不知道为什么。我想这是一个简单的语法错误,但我看不出是什么问题。

PlannedCourses可观察数组是一个动态对象,它正确地获取PlannedCourses列表。它是在自身的上下文中定义的,但是我没有正确地将它传递给totalCredits computed函数。

我希望这足够清楚。谢谢你的帮助!

注意:所有其余的代码都按预期工作。唯一不能正常工作的部分是totalCredits计算函数。我不确定ko.utils.arrayForEach中是否有任何内容正在工作,因为我还没有能够做到这一点。

你将需要改变你的方式填充你的Semesters可观察数组使用一个构造函数,以获得this的正确作用域的引用:

function semester(name, code) {
    this.Name = name;
    this.Code = code;
    this.PlannedCourses = ko.observableArray([]);
    this.totalCredits = ko.computed(function(){
        var total = 0;
        ko.utils.arrayForEach(this.PlannedCourses(), function (course) {
            //Note the change to "this.PlannedCourses()" above to get the underlying array
            total += course.MinHours();
        });
        return total;
    }, this); //now we can pass "this" as the context for the computed
}

看看我们现在如何将一个对象传递给ko.computed的第二个参数,以用作内部函数中this的上下文。有关更多信息,请参阅knockout文档:management 'this'。

然后在填充数组时创建新的semester实例:

Semesters: ko.observableArray([
    new semester("Fall", "300"),
    new semester(...)
]);

这种方法也意味着你有一种一致的方式来创建你的semester对象(计算只定义一次),而不是可能在你最初可能有的任何重复中加入拼写错误等。

正如其他人已经提到的,你的this不是你想的那样。在您的示例中,上下文应按如下方式传递给计算对象:

totalCredits: ko.computed(function() {
    // Computation goes here..
}, this)

另一种方法是在对象创建期间将正确的this存储到某个局部变量中(例如var self = this;,然后使用self而不是this)。

然而,ko.utils.arrayForEach不能处理可观察数组,但可以处理纯JavaScript数组,所以你应该打开可观察数组来访问底层数组的元素:

ko.utils.arrayForEach(this.PlannedCourses(), function(course) { 
    // ...
});
// Or
ko.utils.arrayForEach(ko.unwrap(this.PlannedCourses), function(course) { 
    // ... 
});

scope (this)不是你想的那样

见http://knockoutjs.com/documentation/computedObservables.html

尝试添加上下文,如下所示:

Semesters: ko.observableArray([
{
    semesterName: "Fall",
    semesterCode: "300",
    PlannedCourses: ko.observableArray([]),
    totalCredits: ko.computed(function(){
        var total = 0;
        ko.utils.arrayForEach(this.PlannedCourses, function (course) {
            total += course.MinHours();
        });
        return total;
    }, this), // new context passed in here
},
...

这样做会在数组项本身的上下文中传递给计算函数。

编辑:您可能需要访问循环中的学期对象,并添加一些方法来引用当前项:

Semesters: ko.observableArray([
{
    semesterName: "Fall",
    semesterCode: "300",
    PlannedCourses: ko.observableArray([]),
    totalCredits: ko.computed(function(){
        var total = 0;
        for( var i = 0, len = Semesters().length; i < len; i++ ) {
            // check current array item, possibly add an id?
            if( Semesters()[i].semesterName === "Fall" &&
                Semesters()[i].semesterCode === "300" ) {
                ko.utils.arrayForEach(Semesters()[i].PlannedCourses, function (course) {
                   total += course.MinHours();
                });
                break; // done searching
            }
        }
        return total;
    })
},