Приведение json в соответствие с Bootstrap Treeview.

Я пытаюсь найти лучший способ преобразовать некоторые данные JSON в формат, запрошенный для начальной загрузки дерева. Моей первоначальной мыслью было создать какую-то рекурсивную функцию, чтобы пройти и модифицировать все, но у меня есть некоторые реальные трудности в достижении этого. Любые советы будут высоко ценится!

Вот консольный журнал данных, возвращаемых моим сервисом:

Object
  England: Object
    London: Object
      Bayerische Staatsbibliothek: Object
        Cod. arab. 1251: Array[1]
          0: Object
            key1: "adflkjadf",
            key2: "adflkjadfk",
            key3: "adlkfjadf",
            __proto__: Object
            length: 1
          text: "Cod. arab. 1251"
          __proto__: Array[0]
        Cod. arab. 1252: Array[1]
        Cod. arab. 1253: Array[1]
        Cod. arab. 1254: Array[1]
        Cod. arab. 1255: Array[1]
        Cod. arab. 1256: Array[1]
        Cod. arab. 1257: Array[1]
        Cod. arab. 1258: Array[1]
        Cod. arab. 1259: Array[1]
        Cod. arab. 1260: Array[1]
  Germany: Object
    Munich: Object
      Bayerische Staatsbibliothek: Object
        Cod. arab. 1251: Array[1]
          0: Object
            key1: "adflkjadf",
            key2: "adflkjadfk",
            key3: "adlkfjadf",
            __proto__: Object
            length: 1
          text: "Cod. arab. 1251"
          __proto__: Array[0]
        Cod. arab. 1252: Array[1]
        Cod. arab. 1253: Array[1]
        Cod. arab. 1254: Array[1]
        Cod. arab. 1255: Array[1]
        Cod. arab. 1256: Array[1]
        Cod. arab. 1257: Array[1]
        Cod. arab. 1258: Array[1]
        Cod. arab. 1259: Array[1]
        Cod. arab. 1260: Array[1]

Вот формат, который необходим для Boostrap-TreeView:

var tree = [
  {
    text: "Parent 1",
    nodes: [
      {
        text: "Child 1",
        nodes: [
          {
            text: "Grandchild 1"
          },
          {
            text: "Grandchild 2"
          }
        ]
      },
      {
        text: "Child 2"
      }
    ]
  },
  {
    text: "Parent 2"
  },
  {
    text: "Parent 3"
  },
  {
    text: "Parent 4"
  },
  {
    text: "Parent 5"
  }
];

Вот моя попытка рекурсивной функции для достижения этой цели:

function format_for_treeview(node) {
  for (var key in node) {
    // skip loop if the property is from prototype
    if (!node.hasOwnProperty(key)) continue;

    if (typeof node === 'object') {
      format_for_treeview(node[key]);
      if (Array.isArray(node)) {
        node[key]['text'] = node[key]['bibliography_text'];
      } else {
        node[key]['text'] = key;
      }
    }
  }  
}

2 ответа

Решение

С помощью следующей ссылки я обнаружил, что функция d3 nest() делает почти то, что мне нужно. Однако мне пришлось раскошелиться на файл d3.js и переименовать имена ключей 'key' и 'values' в функции карты nest()-> records().

Кроме того, я изменил сервис так, чтобы он возвращал массив объектов вместо того, чтобы пытаться группировать внутри сервиса.

  var withText = jsondata.map(function(i) {
    i['text'] = i['bibliography_text'];
    return i;
  });

  var nestedData = d3.nest()
    .key(function(d) { return d.country; })
    .key(function(d) { return d.city; })
    .entries(withText);

Полученный результат дает мне массив в точности как var tree = [...] вышеперечисленное.

Если тебе надо bootstrap treeview и хочу разобрать произвольное JSON данные в его формате. Вы можете использовать этот рекурсивный function, Я только что внес несколько изменений в ваш оригинальный код.

function format_for_treeview(node) {
  for (var key in node) {
    // skip loop if the property is from prototype
    if (!node.hasOwnProperty(key)) continue;

    if (typeof node === 'object') {
      format_for_treeview(node[key]);
      if (Array.isArray(node)) {
        node[key]['text'] = node[key]['bibliography_text'];
      } else {
        node[key]['text'] = key;
      }
    }
  }  
}

Изменение этого будет работать так, как вы ожидали. (См. Фрагмент кода ниже.)

function format_for_treeview(data, arr) {
  for (var key in data) {
     if(Array.isArray(data[key]) || data[key].toString() === "[object Object]") {
        // when data[key] is an array or object
        var nodes = [];
        var completedNodes = completeNodes(data[key], nodes);
        arr.push({ text: key, nodes: completedNodes });
     } else {
        // when data[key] is just strings or integer values
        arr.push({ text: key + " : " + data[key] });
     }
  }  
  return arr;
}

var data = {
  "title": "Person",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "age": {
      "description": "Age in years",
      "type": "integer",
      "minimum": 0
    }
  },
  "required": ["firstName", "lastName"]
};

$(document).ready(function() {
  function format_for_treeview(data, arr) {
    for (var key in data) {
      if (Array.isArray(data[key]) || data[key].toString() === "[object Object]") {
        // when data[key] is an array or object
        var nodes = [];
        var completedNodes = format_for_treeview(data[key], nodes);
        arr.push({
          text: key,
          nodes: completedNodes
        });
      } else {
        // when data[key] is just strings or integer values
        arr.push({
          text: key + " : " + data[key]
        });
      }
    }
    return arr;
  }


  $("#my-treeview").treeview({
    color: "#428bca",
    expandIcon: "glyphicon glyphicon-stop",
    collapseIcon: "glyphicon glyphicon-unchecked",
    showTags: true,
    data: format_for_treeview(data, [])
  });

});
<link href="https://jonmiles.github.io/bootstrap-treeview/bower_components/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://jonmiles.github.io/bootstrap-treeview/js/bootstrap-treeview.js"></script>
<div id="my-treeview"></div>

Вы можете настроить push часть, чтобы сделать "ключ: значение" более заметным, вставив строку HTML между ними, как показано ниже.

arr.push({ text: "<span class="key-stub"> + key + "</span>", nodes: completedNodes });

Лично, если вам просто нужна функция, которая преобразует JSON в виде дерева, вам не нужно бороться с этим. Просто подумайте об использовании этого. Нет преобразования не требуется.

Другие вопросы по тегам