在子对象中显示筛选列表的挖空 js.访问要过滤的父对象列表
Knockout js displaying a filtered list in a child object. Accessing the parent object list to filter
>我目前有一个学生列表和一个学校对象中的类列表。我希望每个类对象都能够根据类 id 属性显示筛选的学生列表。
我尝试通过自定义绑定访问父对象,但没有任何成功。
也许我看错了问题?我花了几天时间解决这个问题,无论我以哪种方式解决它,我总是需要访问父对象上的值。
有什么方法可以访问我需要的东西吗?我开始认为无法访问全局样式变量。
function School()
{
var self = this;
self.ClassVMs = ko.observableArray([]).indexed('Number');
self.ChildVMs = ko.observableArray([]).indexed('Number');
}
function ClassVM(classId, text)
{
var self = this;
self.Number = ko.observable();
self.Text = ko.observable(text);
self.ClassId = ko.observable(classId);
}
function ChildVM(classId, text)
{
var self = this;
self.Number = ko.observable();
self.ClassId = ko.observable(classId);
self.Text = ko.observable(text);
}
我对我的设置有一个小提琴。感谢任何和所有指导。谢谢
你不需要全局变量来解决这个问题。淘汰赛已经$root
,$parent
稍微超出你在foreach
内的范围。此外,如果确实需要,您始终可以确保视图模型获得另一种类型的视图模型作为其依赖项。事实上,如果一个视图模型有一个子视图模型的列表,它已经有这样的依赖关系。
您需要考虑的是您的UI/UX会是什么样子。您是否设计视图模型以支持用户"查看"学生并让他/她注册课程的视图?还是应用程序用户正在查看课程并逐个添加学生?
这是一个变体,显示了两者的一点点:
function School(classes) {
var self = this;
self.classes = ko.observableArray(classes);
self.students = ko.observableArray([]);
self.enroll = function(child, someClass) {
if (self.students().indexOf(child) < 0) {
self.students.push(child);
}
if (someClass.students().indexOf(child) < 0) {
someClass.students.push(child);
}
};
self.enrollNewChild = function(someClass) {
if (!!someClass.childToBeEnrolled()) {
self.enroll(someClass.childToBeEnrolled(), someClass);
someClass.childToBeEnrolled(null);
}
};
self.enrollInClass = function(child) {
if (!!child.classToBeEnrolledIn()) {
self.enroll(child, child.classToBeEnrolledIn());
child.classToBeEnrolledIn(null);
}
};
}
function Class(id, txt) {
var self = this;
self.id = ko.observable(id);
self.txt = ko.observable(txt);
self.students = ko.observableArray([]);
self.studentsCsv = ko.computed(function() {
return self.students().map(function(s) { return s.txt(); }).join(", ");
});
self.childToBeEnrolled = ko.observable(null);
}
function Child(id, txt) {
var self = this;
self.id = ko.observable(id);
self.txt = ko.observable(txt);
self.classToBeEnrolledIn = ko.observable(null);
}
var english = new Class(1, "English 1");
var math1 = new Class(2, "Mathematics 1");
var math2 = new Class(2, "Mathematics 2");
var john = new Child(1, "John Doe");
var mary = new Child(1, "Mary Roe");
var rick = new Child(1, "Rick Roll");
var marc = new Child(1, "Marcus Aurelius");
var school = new School([english, math1, math2]);
ko.applyBindings(school);
// Method 1:
school.enroll(john, english);
school.enroll(john, math2);
school.enroll(marc, english);
school.enroll(mary, math2);
school.enroll(mary, english);
school.enroll(rick, english);
school.enroll(rick, math1);
td { background-color: #eee; padding: 2px 10px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<h3>Classes:</h3>
<table>
<tbody data-bind="foreach: classes">
<tr>
<td><span data-bind="text: txt"></span></td>
<td><span data-bind="text: studentsCsv"></span></td>
<td>
Add student
<select data-bind="options: $root.students, value: childToBeEnrolled, optionsText: 'txt', optionsCaption: 'Choose...'"></select>
<button data-bind="click: $root.enrollNewChild">enroll now</button>
</td>
</tr>
</tbody>
</table>
<h3>School Students</h3>
<table>
<tbody data-bind="foreach: students">
<tr>
<td><span data-bind="text: txt"></span></td>
<td>
Enroll in:
<select data-bind="options: $root.classes, optionsText: 'txt', value: classToBeEnrolledIn, optionsCaption: 'Choose...'"></select>
<button data-bind="click: $root.enrollInClass">enroll now</button>
</td>
</tr>
</tbody>
</table>
它不会直接回答您的问题("根据类 id 属性显示过滤的学生列表"),因为我认为这是一个 XY 问题,您最好尝试找到像上面这样的解决方案,其中您有适当的引用,而不必使用id
和某种查找机制。
是的,我可以看到它如何被认为是一个 XY 问题。你们俩都以不同的方式看待它,这是一个很大的帮助。
我最初想要的方式看起来不可行。我的折衷方案是将计算添加到根视图模型并以这种方式显示列表。
function School()
{
var self = this;
self.ClassVMs = ko.observableArray([]).indexed('Number');
self.ChildVMs = ko.observableArray([]).indexed('Number');
self.DisplayClassId = ko.observable(1);
self.Display = function(x)
{
console.log(x);
self.DisplayClassId(x);
}
}
var viewModel = new School();
viewModel.filteredItems = ko.computed(function () {
var filter = viewModel.DisplayClassId();
if (!filter) {
return viewModel.ChildVMs();
} else {
var filtered = ko.utils.arrayFilter(viewModel.ChildVMs(), function (item) {
return (item.ClassId() === filter);
});
return filtered;
}
})
小提琴供参考
相关文章:
- 如何使用json将对象列表从java转换为javascript
- 从HTTPGET返回一个自定义对象列表,以便在Angular 2应用程序中使用
- 当属性不一致时,如何根据属性对JS对象列表进行排序
- 如何使用Javascript客户端对象模型检索Sharepoint 2010列表项权限
- 用javascript从列表对象(JSON的)构建diffrent选项卡
- 如何更改列表.js列表对象中的选项
- 如何使用变量值将列表<对象>序列化为 JSON
- 将列表对象从javascript转换为JSON
- 将对象推入对象列表对象
- 如何从列表对象生成li和锚点标记
- AngularJS-通过dons't在ng模型中设置列表对象
- 隐藏一定数量的列表对象
- 要切换的Javascript类列表对象和查询选择器
- 从动态列表对象中获取对象
- jPlayer不播放播放列表对象的全局声明中的歌曲
- Spring MVC @ResponseBody, JSON, JSP.试图返回列表<对象>从控制器到JSP
- Javascript列表对象可以'不添加JSON?node . js,重火力点
- javascript从文件列表创建文件列表对象
- 流星 - 在列表对象中呈现所有者的名称
- UndefinedError:列表对象没有未定义元素