如何在 Knockout.js 中嵌套 object

How to nest object in Knockout.js

在 Knockout.js 中,在数组中嵌套 object 的最佳方法是什么?

我正在尝试有一个按一组课程标题排序的可观察对象,并且在内部会有不同的课程提供给同一组的学生属性(课程代码)。

这是我的代码片段

function course(_id, _code, _title, _campus) {
    var self = this;
    this.id = ko.observable(_id);
    this.courseCode = ko.observable(_code);
    this.courseTitle = ko.observable(_title);
    this.coursecampus = ko.observable(_campus);
}

function gpCourseProperties(_code, _isHidden) {
    var self = this;
    this.gpCode = ko.observable(_code);
    this.hide = ko.observable(_isHidden);
    this.courses = ko.observableArray();

    this.addCourse = function (_id, _courseCode, _courseTitle, _courseCampus) {
        self.courses.push(new course(_id, _courseCode, _courseTitle, _courseCampus));
    }

    this.switchMutated = function (code) {
        self.hide(!self.hide());
    };
    this.switchText = ko.computed(function () {
        if (self.hide() == true) {
            return '+'
        }
        return '-';
    }, this);
}

function ViewModel() {
    var self = this;
    this.gpCourseProp = ko.observableArray();

self.gpCourseProp.push(new gpCourseProperties("MATH1030", true));
self.gpCourseProp.push(new gpCourseProperties("MATH1006", true));
self.gpCourseProp.push(new gpCourseProperties("MATH1046", true));

    for (i = 0; i < self.gpCourseProp().length; i++) {
    if (self.gpCourseProp()[i].gpCode == "MATH1030") {
        self.gpCourseProp()[i].addCourse(new course("1", "MATH1030", "Calculus", "City1"));
        self.gpCourseProp()[i].addCourse(new course("2", "MATH1030", "Calculus", "City2"));
        self.gpCourseProp()[i].addCourse(new course("3", "MATH1030", "Calculus", "City3"));
    }
    if (self.gpCourseProp()[i].gpCode == "MATH1006") {
        self.gpCourseProp()[i].addCourse(new course("4", "MATH1006", "Linear algebra", "City1"));
        self.gpCourseProp()[i].addCourse(new course("6", "MATH1006", "Linear algebra", "City2"));
    }
    if (self.gpCourseProp()[i].gpCode == "MATH1046") {
        self.gpCourseProp()[i].addCourse(new course("5", "MATH1046", "Discrete Math", "City1"));
        self.gpCourseProp()[i].addCourse(new course("7", "MATH1046", "Discrete Math", "City2"));
    }
    }
}

var vm = new ViewModel();
ko.applyBindings(vm);
    tr.mutated {
        display: none;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>Course Code</th>
            <th>Course Title</th>
            <th>Course Campus</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: gpCourseProp">
        <tr class="table-dark">
            <td></td>
            <td><span data-bind="text: $data.gpCode"></span></td>
            <td><span></span></td>
            <td></td>
        </tr>
        <!-- ko foreach: $data.courses -->
        <tr data-bind="css: { mutated: $parent.mutated.hide() == true }">
            <td><span data-bind="text: $data.id"></span></td>
            <td><span data-bind="text: $data.courseCode"></span></td>
            <td><span data-bind="text: $data.courseTitle"></span></td>
            <td><span data-bind="text: $data.coursecampus"></span></td>
        </tr>
        <!-- /ko -->
    </tbody>
</table>

我遇到的问题是尝试将课程添加到 gpCourseProperties。

主要问题是:

  • 当您初始化数据时,您只 pushgpCourseProperties 的参数传递给可观察数组。您需要使用 new.
  • 构建视图模型
  • 当您为 courseProperties 创建 course 内容时,您会选中 gpCode === "Some string"。由于 gpCodeobservable,您需要使用 () 提取它的值才能使它永远为真。

这是一个更新版本,只需要进行最少的更改即可使其正常工作。 (注意,出于调试目的,我删除了隐藏某些行的 CSS)。

已在评论中标记修复。

function course(_id, _code, _title, _campus) {
    var self = this;
    this.id = ko.observable(_id);
    this.courseCode = ko.observable(_code);
    this.courseTitle = ko.observable(_title);
    this.coursecampus = ko.observable(_campus);
}

function gpCourseProperties(_code, _isHidden) {
    var self = this;
    this.gpCode = ko.observable(_code);
    this.hide = ko.observable(_isHidden);
    this.courses = ko.observableArray();

    this.addCourse = function (_id, _courseCode, _courseTitle, _courseCampus) {
        self.courses.push(new course(_id, _courseCode, _courseTitle, _courseCampus));
    }

    this.switchMutated = function (code) {
        self.hide(!self.hide());
    };
    this.switchText = ko.computed(function () {
        if (self.hide() == true) {
            return '+'
        }
        return '-';
    }, this);
}

function ViewModel() {
    var self = this;
    this.gpCourseProp = ko.observableArray();

    // Fix 1:
    //                     vvvvvvvvvvvvvvvvvvvvvvv                v
    self.gpCourseProp.push(new gpCourseProperties("MATH1030", true));
    self.gpCourseProp.push(new gpCourseProperties("MATH1006", true));
    self.gpCourseProp.push(new gpCourseProperties("MATH1046", true));

    for (i = 0; i < self.gpCourseProp().length; i++) {
        // Fix 2:
        //                               vv
        if (self.gpCourseProp()[i].gpCode() == "MATH1030") {
            self.gpCourseProp()[i].addCourse("1", "MATH1030", "Calculus", "City1");
            self.gpCourseProp()[i].addCourse("2", "MATH1030", "Calculus", "City2");
            self.gpCourseProp()[i].addCourse("3", "MATH1030", "Calculus", "City3");
        }
        if (self.gpCourseProp()[i].gpCode() == "MATH1006") {
            self.gpCourseProp()[i].addCourse("4", "MATH1006", "Linear algebra", "City1");
            self.gpCourseProp()[i].addCourse("6", "MATH1006", "Linear algebra", "City2");
        }
        if (self.gpCourseProp()[i].gpCode() == "MATH1046") {
            self.gpCourseProp()[i].addCourse("5", "MATH1046", "Discrete Math", "City1");
            self.gpCourseProp()[i].addCourse("7", "MATH1046", "Discrete Math", "City2");
        }
    }
}

var vm = new ViewModel();
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>Course Code</th>
            <th>Course Title</th>
            <th>Course Campus</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: gpCourseProp">
        <tr class="table-dark">
            <td></td>
            <td><span data-bind="text: gpCode"></span></td>
            <td><span></span></td>
            <td></td>
        </tr>
        <!-- ko foreach: courses -->
        <tr data-bind="css: { mutated: $parent.hide() == true }">
            <td><span data-bind="text: id"></span></td>
            <td><span data-bind="text: courseCode"></span></td>
            <td><span data-bind="text: courseTitle"></span></td>
            <td><span data-bind="text: coursecampus"></span></td>
        </tr>
        <!-- /ko -->
    </tbody>
</table>