我有以下嵌套数据结构(viewmodel):
projects ( projectid, project_name )
|--- subprojects ( parent_projectid, subproject_name )
我想将“子项目”过滤为“parent_projectid”,这是来自父项目(“projectid”)的id。 “tbody”应自动呈现子项目,例如:
<tbody >
<!-- ko foreach: projects -->
<tr>
<td data-bind="text: projectid"></td>
<td data-bind="text: project_name "></td>
<td class="add" href="#" data-bind="click: addsubproject">Add Subproject</td>
</tr>
*** here should the filter applied : ***
<!-- ko foreach: subprojects // show only subprojects with "parent_projectid = projectid" -->
<tr>
<td></td>
<td data-bind="text: parent_projectid"></td>
<td data-bind="text: subproject_name "></td>
</tr>
<!-- /ko -->
<!-- /ko -->
</tbody>
我该如何申请?我不想在viewmodel中计算某些内容来获取已过滤的子项目,过滤器“机制”应仅在呈现tbody中工作(如果可能)
答案 0 :(得分:2)
一旦你不再认为你的观点应该是聪明的,这很容易。您的观点应该反映您的模型 - 不要强迫它做更多的事情。
如果要显示此结构:
// we only really have one type of object in your scenario, let's call it "Project"
function Project(data) {
this.id = data.id;
this.name = ko.observable(data.name);
this.children = ko.observableArray(ko.utils.arrayMap(data.children, function (child) {
// NB this is recursive
return new Project(child);
}));
}
// this will be the main viewmodel
function ProjectTree() {
var root = new Project({id: 0, name: "root", children: data});
this.projects = root.children;
}
假设您从服务器检索的data
是一个平面的项目对象数组,让我们将它们预处理到树中。再次 - 这是关键部分 - 如果你想显示树形数据,你应该有树形数据。
$.get("projects.json").then(function (data) {
var index = {}, children = {};
// index objects by id and by parentid
data.forEach(function (project) {
index[project.id] = project;
if (project.parentid in index) {
children[project.parentid].push(project);
} else {
children[project.parentid] = [project];
}
});
// link up everything into a tree
Object.keys(index).forEach(function (project) {
project.children = children[project.id] || [];
});
return children[0]; // or whatever the parent ID of top level projects is
}).done(function (data) {
var vm = new ProjectTree(data);
ko.applyBindings(vm);
});
现在视图可以是它应该是什么 - 直截了当:
<tbody data-bind="foreach: projects">
<tr>
<td data-bind="text: id"></td>
<td data-bind="text: name"></td>
<td class="add" href="#" data-bind="click: addsubproject">Add Subproject</td>
</tr>
<!-- ko foreach: children -->
<tr>
<td></td>
<td data-bind="text: $parent.id"></td>
<td data-bind="text: name"></td>
</tr>
<!-- /ko -->
</tbody>