如何在 Knockout.js 中嵌套对象
Posted
技术标签:
【中文标题】如何在 Knockout.js 中嵌套对象【英文标题】:How to nest object in Knockout.js 【发布时间】:2021-06-21 04:45:57 【问题描述】:在 Knockout.js 中,将对象嵌套在数组中的最佳方法是什么?
我试图有一个按一组课程标题排序的可观察对象,并且在里面会有不同的课程提供给具有相同组属性(课程代码)的学生。
这是我的sn-p
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。
【问题讨论】:
'我有 jsfiddle,但我有一些问题。这里是 jsfiddle。” 请使用 Stack Snippets([<>]
工具栏按钮)在这里,现场执行您的可运行示例;here's how to do one。
【参考方案1】:
主要问题是:
初始化数据时,您只需将push
的参数gpCourseProperties
传递给可观察数组。您需要使用new
构建视图模型。
当您为您的courseProperties
创建course
内容时,您检查gpCode === "Some string"
。由于gpCode
是observable
,因此您需要使用()
提取它的值,这样才能永远成立。
这是一个更新版本,只需进行最少的更改即可使其正常工作。 (注意,出于调试目的,我删除了隐藏某些行的 CSS)。
修复在 cmets 中标记。
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>
【讨论】:
以上是关于如何在 Knockout.js 中嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章
knockout.js 数据中的嵌套 foreach 显示但未正确显示
knockout.js remove 不适用于主视图模型中的嵌套视图模型和视图模型