Приведение 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
в виде дерева, вам не нужно бороться с этим. Просто подумайте об использовании этого. Нет преобразования не требуется.