Как создать родительское / дочернее гнездо на стороне клиента? - PullRequest
2 голосов
/ 13 марта 2012

Я просмотрел множество родительских / дочерних массивов / объектов / любых других вопросов здесь и в других местах и ​​не смог решить мою проблему. Я знаю, что это немного долго, но я хотел убедиться, что я предоставляю вам достаточно информации, ребята.

Вот что я хочу сделать:

  1. У меня есть несколько <div> элементов на странице с отношениями родитель / потомок, сгенерированных через php из моей базы данных
  2. Я хочу использовать эти элементы в качестве источника данных для дендрограммы D3.js (диаграмма дерева связей узлов http://mbostock.github.com/d3/ex/cluster.html)
  3. Я храню их с вложенными левыми / правыми установленными значениями, а также со значениями parentID, поэтому я могу добавить атрибуты ID, parentID, rgt, lft и глубины к элементам <div>, чтобы у меня была возможность использовать все необходимое для генерации отношения родитель / ребенок на стороне клиента
  4. По разным причинам вместо создания файла JSON на стороне сервера для использования в качестве источника данных мне нужно создать его на стороне клиента на основе атрибутов в # 3
  5. Мне было трудно заставить работать различные предлагаемые функции javascript, и во всех найденных мной примерах D3 используется либо существующий файл JSON, либо сгенерированный файл на основе математики, а не атрибуты элементов, уже находящихся на странице

Вот пример того, что у меня уже работает с дендрограммой D3, но она не генерируется динамически:

var tree3 = 
{"sid": "1", "children": [
    {"sid": "2", "children": [
        {"sid": "5", "children": [
            {"sid": "75"},
            {"sid": "85", "children": [
                {"sid": "87"}, ...

Чтобы дать вам представление о том, где находятся эти атрибуты в DOM, я первоначально попробовал следующее, но, конечно, он не создает никакой иерархии:

function tree() {
    var tree=[];
    $("article").each(function(){
        tree.push({
            sid:$(this).attr("sid"), 
            l:$(this).attr("l"), 
            r:$(this).attr("r"),
            pid:$(this).attr("pid")
        });
    });
    return tree;
}

Я безуспешно возился с вариантами ниже, чтобы получить вложенный массив:

function tree2() {
   $("article").(function(d) {
       return d.parent().attr("pid") === 0;
}, function(parent, child) {
    return parent.attr("pid") === child.parent().attr("sid");
}).toArray();
}

Итак, я схожу с ума, пытаясь создать правильно вложенный массив javascript, но до меня дошло, что мне это может не понадобиться, и что селекторов данных и методов D3 может быть достаточно. Не могли бы вы помочь мне с кодом:

  1. Извлеките необходимые атрибуты, чтобы сгенерировать отношения родитель / потомок в функции D3 («sid» - это идентификатор) или, если это невозможно,
  2. Создайте необходимый массив или подобный массиву объект в javascript для использования D3 (с идентификатором sid).

Заранее спасибо.

1 Ответ

1 голос
/ 13 марта 2012

Вам нужно стать рекурсивным!По сути, уловка заключается в том, чтобы передать текущий родительский элемент в процессе работы, что изменяет контекст и позволяет вам идти по дереву.

Обновление: Рабочая скрипка .

Предположим, что ваша структура HTML выглядит примерно так:

<div sid="1" pid="">
    <div sid="1.1" pid="1">
        <div sid="1.1.1" pid="1.1">
        </div>
    </div>
</div>

Вы можете сделать что-то вроде этого:

var _json = {};

function addTreeNode(div, parentObj) {

    var childObj = {
        sid: $(div).attr("sid"),
        pid: $(div).attr("pid")
    }

    // add this to it's parent in the JSON hierarchy
    if (!parentObj.children) parentObj.children = [];
    parentObj.children.push(childObj);

    // keep adding for all children div's
    $(div).find("div").each(function() {
        addTreeNode(this, childObj);
    });
}

// start at the roots, it will magically work it's way out to the leaves
$("body > div").each(function(){
    addTreeNode(this, _json);
});

console.log(_json);

Обратите внимание, что если вашДерево достаточно большое, вы вызовете переполнение стека, особенно в IE.В этом случае вам нужно будет переключить это значение с рекурсии на итерацию .Впрочем, это не так красиво.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...