Я хотел бы построить иерархию динамически, при этом каждый узел, созданный как слой / уровень в иерархии, имеет свой собственный массив узлов. ЭТО ДОЛЖНО ФОРМИРОВАТЬ СТРУКТУРУ ДЕРЕВА. Должен быть корневой узел и неопределенное количество узлов и уровней, составляющих размер иерархии. Ничего не должно быть исправлено, кроме корневого узла. Мне не нужно читать или искать иерархию, мне нужно ее построить. Массив должен начинаться с {"name": "A", "children": []} и каждый новый узел в качестве уровней будет создаваться {"name": "A", "children": [ЗДЕСЬ - {"name": «А», «дети»: []}]}. В дочернем массиве все глубже и глубже. Обычно перед вызовом в массиве не должно быть значений, кроме, возможно, корневого узла. После вызова функции массив должен состоять из требуемых узлов числа, которое может меняться при каждом вызове в зависимости от результатов запроса к базе данных. Каждый дочерний массив будет содержать одно или несколько значений узла. Должно быть как минимум 2 уровня узлов, включая корневой. Изначально это должен быть пустой холст, а не предопределенные значения массива.
Динамическая древовидная структура Javascript
Ответы (2)
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": []
}
]
}
]
}
person
balafi
schedule
21.09.2012
Это требует добавления узлов в определенном порядке; если запрос SQL возвращает потомков раньше родителей, вам придется переупорядочить узлы, прежде чем вы сможете использовать addChild для создания представления JavaScript.
- person tucuxi; 21.09.2012
не уверен. Вы можете начать снизу (или с любого места). например: var bottom = new Tree (D1); var выше = новое дерево (C1); выше.addNode (внизу); .. но все же может быть не совсем то, что вам нужно
- person balafi; 21.09.2012
Итак, ваши узлы имеют свойство 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/ для рабочего примера.
person
tucuxi
schedule
20.09.2012
Могу ли я скопировать ваш код вместо раздела var treeData моего кода? Как вы можете видеть в моем коде, я вызываю var treeData для представления всего сгенерированного дерева.
- person user1684586; 21.09.2012
Ok. Но мне нужно сохранить свойство name: и свойство children: array узлов, чтобы добиться формата дерева. Не табличный формат. Вопрос заключался в том, как создать этот формат для узлов динамическим образом, чтобы он мог поддерживать любое заданное количество узлов / уровней в иерархии.
- person user1684586; 21.09.2012
Я хорошо выгляжу, когда использую консоль. Мне нужно будет выполнить интеграцию с моим кодом, чтобы узнать, правильно ли он. Кстати, большое спасибо :) Кроме того, ваш код допускает фиксированное количество узлов, как я описал в моем примере из 4 наборов узлов, или цикл в вашем коде допускает вариантное количество узлов при каждой обработке?
- person user1684586; 21.09.2012
Большое спасибо. Отлично работает. Теперь все, что мне нужно сделать, это использовать его с mysql. :)
- person user1684586; 21.09.2012