动态Javascript树形结构

3
我想动态构建分层结构,每个节点作为层/级别在层次结构中创建并具有自己的节点数组。这应该形成树状结构。除了根节点以外,没有固定的节点或层级数。我不需要读取或搜索层次结构,我需要构造它。
数组应始于 {"name" : "A", "children" : []} ,每个新节点作为层级将创建 {"name" : "A", "children" : [HERE-{"name" : "A", "children" : []}]}。向更深的子数组中加入更多节点。基本上,在调用之前,数组不应包含任何值,除了可能的根节点。在函数调用后,数组应包含所需的节点,其数量可能因数据库查询结果而异。每个子数组都将包含一个或多个节点值。应至少有2个节点层级,包括根节点。
它最初应该是一个空白画布,即没有预定义的数组值。
2个回答

5
    function Tree(name,child){
        this.name = name;
        this.children = child || [];
        this.addNode = function (parent){
            this.children = parent;
        }
        this.addChild = function (parentName){
            this.children.push(new Tree(parentName));
        }
    }

    var tree = new Tree("A"); // create a tree (or a portion of a tree) with root "A" and empty children
    tree.addChild("B1");   // A -> B1
    tree.addChild("B2");   // A -> B2
    var subTree1 = new Tree("C1"); // create a sub tree
    subTree1.addChild("D1");   // C1 -> D1
    subTree1.addChild("D2");   // C1 -> D2
    tree.children[0].addNode(subTree1);   // add this sub tree under A->B1
    // Tree now is:  A--> B1
    //                      C1
    //                        D1
    //                        D2
    //                    B2
    tree.children[1].addChild("C2");
    // Tree now is:  A--> B1
    //                      C1
    //                        D1
    //                        D2
    //                    B2
    //                      C2
    //tree.children[0].addChild("C4");
    // Tree now is:  A--> B1
    //                      C1
    //                        D1
    //                        D2
    //                      C4
    //                    B2
    //                      C2    
    console.log(JSON.stringify(tree));

输出

{
  "name": "A",
  "children": [
    {
      "name": "B1",
      "children": {
        "name": "C1",
        "children": [
          {
            "name": "D1",
            "children": []
          },
          {
            "name": "D2",
            "children": []
          }
        ]
      }
    },
    {
      "name": "B2",
      "children": [
        {
          "name": "C2",
          "children": []
        }
      ]
    }
  ]
}

这需要按特定顺序添加节点;如果SQL查询返回子节点先于父节点,您将不得不重新排序节点,然后才能使用addChild构建JavaScript表示。 - tucuxi
不确定。你可以从底部(或任何地方)开始。例如: var bottom = new Tree("D1"); var higher = new Tree("C1"); higher.addNode(bottom); .. 但仍然可能不是你所需要的。 - balafi

4
所以你的节点有一个name:属性和一个children:数组属性。
通常,数据库将树形结构存储在表中。
node-id, parent-id, value1, ..., valueN

如果您存储深度优先访问顺序和深度优先返回顺序,可以获得某些优势;如果需要详细信息,请在评论中询问。

如果您进行单个查询并将此数据转换为JSON格式,您将得到类似以下内容的结果(仅供参考):

[{id: "0", parent: "-1", name: "A2"}, {id: "1", parent: "0", name: "A3"}, 
 {id: "2", parent: "1", name: "A31"}, {id: "3", parent: "2", name: "A311"}, 
 {id: "4", parent: "2", name: "A312"}]

你可以使用以下代码将其转换为{name: children:}格式:

  // data is an array in the above format
function toTree(data) {
   var childrenById = {}; // of the form id: [child-ids]
   var nodes = {};        // of the form id: {name: children: }
   var i, row;
   // first pass: build child arrays and initial node array
   for (i=0; i<data.length; i++) {
       row = data[i];
       nodes[row.id] = {name: row.name, children: []};
       if (row.parent == -1) { // assume -1 is used to mark the root's "parent"
          root = row.id; 
       } else if (childrenById[row.parent] === undefined) {
          childrenById[row.parent] = [row.id];
       } else {
          childrenById[row.parent].push(row.id);
       }
   }
   // second pass: build tree, using the awesome power of recursion!
   function expand(id) {
       if (childrenById[id] !== undefined) {
           for (var i=0; i < childrenById[id].length; i ++) {
               var childId = childrenById[id][i];
               nodes[id].children.push(expand(childId));
           }
       }
       return nodes[id];
   }
   return expand(root);
}

请查看http://jsfiddle.net/z6GPB/,以获取一个可工作的示例。


我需要将你的代码复制到我的代码中 var treeData 部分吗?正如你在我的代码中看到的,我调用 var treeData 来表示整个生成的树。 - user1684586
好的。但我需要保留节点的名称:property和children:array属性,以实现树形格式。而不是表格格式。问题是如何以动态方式构建节点的此格式,以支持层次结构中任意给定数量的节点/级别。 - user1684586
当我使用控制台时,它看起来很好。我将不得不与我的代码集成以确定它是否正确。顺便说一句,非常感谢 :) 另外,您提供的代码是否允许固定数量的节点,就像我描述的4个节点集示例一样,还是您的代码中的循环允许处理可变数量的节点? - user1684586
非常感谢。它运行得很好。现在我只需要把它与mysql一起使用。 :) - user1684586

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接