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>(甚至为空)。

希望您理解该方法。