knockout - 根据指向主键列的父id绑定树结构
knockout - bind tree structure based on parent id pointing to the primary key column
我正在尝试通过以下 this 敲除文档将存储过程返回的数据绑定到树结构中。
我正在从以下格式的存储过程中获取数据:
ID | Name | ParentID
1 | Parent 1 | 0
2 | Parent 2 | 0
3 | Parent 1 Child 1 | 1
4 | Parent 2 Child 1 | 2
5 | Parent 1 Child 1 Child | 3
6 | Parent 2 Child 1 Child 1 | 4
7 | Parent 2 Child 1 Child 2 | 4
在 ParentID
列中,0 表示根项,所有其他项都指向父子关系中的 ID
列。可以有 N
级别的父子关系,我需要将它们绑定在树结构中,例如:
Parent 1
Parent 1 Child 1
Parent 1 Child 1 Child
Parent 2
Parent 2 Child 1
Parent 2 Child 1 Child 1
Parent 2 Child 1 Child 2
在文档中,它显示了在 click
事件上绑定子项目,但我需要一次绑定所有项目,这是我感到困惑的部分。有没有其他方法根据上面给出的存储过程结果使用knockout绑定树结构?
最简单的方法是创建 computed
来仅表示源数组中的根项,并创建一个辅助函数来获取当前项的子项:
var treeData = [
{ id: 1, name: "Parent 1", parent_id: 0 },
{ id: 2, name: "Parent 2", parent_id: 0 },
{ id: 3, name: "Parent 1 Child 1", parent_id: 1 },
{ id: 4, name: "Parent 2 Child 1", parent_id: 2 },
{ id: 5, name: "Parent 1 Child 1 Child", parent_id: 3 },
{ id: 6, name: "Parent 2 Child 1 Child 1", parent_id: 4 },
{ id: 7, name: "Parent 2 Child 1 Child 2", parent_id: 4 }
];
function ViewModel(data) {
this.allItems = ko.observableArray(data);
this.rootItems = ko.computed(function(){
return ko.utils.arrayFilter(this.allItems(), function(item){
return item.parent_id == 0;
});
}, this);
this.children = function(parent){
return ko.utils.arrayFilter(this.allItems(), function(item){
return parent.id == item.parent_id;
});
};
}
然后您可以使用命名模板输出任意深度的嵌套列表,例如:
<ul data-bind="template: { name: 'list-item', foreach: rootItems }"></ul>
<script type="text/html" id="list-item">
<li>
<span data-bind="text: name"></span>
<ul data-bind="template: { name: 'list-item', foreach: $root.children($data) }"></ul>
</li>
</script>
结果:http://jsfiddle.net/jwquemL6/
P.S。这是一个非常简化的工作示例,因此您可能希望将所有项目包装到特定的数据结构中,并防止每个 <li>
节点都有 <ul>
(甚至为空)。
希望您理解该方法。
我正在尝试通过以下 this 敲除文档将存储过程返回的数据绑定到树结构中。
我正在从以下格式的存储过程中获取数据:
ID | Name | ParentID
1 | Parent 1 | 0
2 | Parent 2 | 0
3 | Parent 1 Child 1 | 1
4 | Parent 2 Child 1 | 2
5 | Parent 1 Child 1 Child | 3
6 | Parent 2 Child 1 Child 1 | 4
7 | Parent 2 Child 1 Child 2 | 4
在 ParentID
列中,0 表示根项,所有其他项都指向父子关系中的 ID
列。可以有 N
级别的父子关系,我需要将它们绑定在树结构中,例如:
Parent 1
Parent 1 Child 1
Parent 1 Child 1 Child
Parent 2
Parent 2 Child 1
Parent 2 Child 1 Child 1
Parent 2 Child 1 Child 2
在文档中,它显示了在 click
事件上绑定子项目,但我需要一次绑定所有项目,这是我感到困惑的部分。有没有其他方法根据上面给出的存储过程结果使用knockout绑定树结构?
最简单的方法是创建 computed
来仅表示源数组中的根项,并创建一个辅助函数来获取当前项的子项:
var treeData = [
{ id: 1, name: "Parent 1", parent_id: 0 },
{ id: 2, name: "Parent 2", parent_id: 0 },
{ id: 3, name: "Parent 1 Child 1", parent_id: 1 },
{ id: 4, name: "Parent 2 Child 1", parent_id: 2 },
{ id: 5, name: "Parent 1 Child 1 Child", parent_id: 3 },
{ id: 6, name: "Parent 2 Child 1 Child 1", parent_id: 4 },
{ id: 7, name: "Parent 2 Child 1 Child 2", parent_id: 4 }
];
function ViewModel(data) {
this.allItems = ko.observableArray(data);
this.rootItems = ko.computed(function(){
return ko.utils.arrayFilter(this.allItems(), function(item){
return item.parent_id == 0;
});
}, this);
this.children = function(parent){
return ko.utils.arrayFilter(this.allItems(), function(item){
return parent.id == item.parent_id;
});
};
}
然后您可以使用命名模板输出任意深度的嵌套列表,例如:
<ul data-bind="template: { name: 'list-item', foreach: rootItems }"></ul>
<script type="text/html" id="list-item">
<li>
<span data-bind="text: name"></span>
<ul data-bind="template: { name: 'list-item', foreach: $root.children($data) }"></ul>
</li>
</script>
结果:http://jsfiddle.net/jwquemL6/
P.S。这是一个非常简化的工作示例,因此您可能希望将所有项目包装到特定的数据结构中,并防止每个 <li>
节点都有 <ul>
(甚至为空)。
希望您理解该方法。