AngularJS - Json 到树结构
AngularJS - Json to Tree structure
我见过很多将 Json 响应转为 Ul 树结构的答案。
问题是所有这些主题都围绕着一个嵌套的响应指向
parent object 和 child object.
之间的关系
我有一个非嵌套的 Json 响应,通过引用 object 来指示关系 属性。
以下为部分回复:
{"id":"1","parent_id":null,"name":"Item-0"},
{"id":"2","parent_id":"1","name":"Item-1"},
{"id":"3","parent_id":"2","name":"Item-2"},
{"id":"4","parent_id":"2","name":"Item-4"},
{"id":"5","parent_id":"2","name":"Item-5"},
{"id":"6","parent_id":"2","name":"Item-6"},
{"id":"7","parent_id":"2","name":"Item-7"},
{"id":"8","parent_id":"2","name":"Item-8"},
{"id":"9","parent_id":"2","name":"Item-9"},
{"id":"10","parent_id":"1","name":"Item-3"},
{"id":"11","parent_id":"10","name":"Item-10"},
您可能已经注意到每个 object 通过 parent_id 与他的父亲联系,parent_id 与他的 parent 的 ID 相关联。
我尝试创建一个自定义指令来读取响应并通过递归构建树结构。
到目前为止我只成功创建了树的第一层。
Demo
app.directive('tree',function(){
var treeStructure = {
restrict: "E",
transclude: true,
root:{
response : "=src",
Parent : "=parent"
},
link: function(scope, element, attrs){
var log = [];
scope.recursion = "";
angular.forEach(scope.response, function(value, key) {
if(value.parent_id == scope.Parent){
this.push(value);
}
}, log);
scope.filteredItems = log;
scope.getLength = function (id){
var test = [];
angular.forEach(scope.response, function(value, key) {
if(value.parent_id == id){
this.push(value);
}
}, test);
if(test.length > 0){
scope.recursion = '<tree src="scope.response" parent="'+id+'"></tree>';
}
return scope.recursion;
};
},
template:
'<ul>'
+'<li ng-repeat="item in filteredItems">'
+'{{item.name}}<br />'
+'{{getLength(item.id)}}'
+'</li>'
+'<ul>'
};
return treeStructure;
});
app.controller('jManajer', function($scope){
$scope.information = {
legend : "Angular controlled JSon response",
};
$scope.response = [
{"id":"1","parent_id":null,"name":"Item-0"},
{"id":"2","parent_id":"1","name":"Item-1"},
{"id":"3","parent_id":"2","name":"Item-3"},
{"id":"4","parent_id":"2","name":"Item-4"},
{"id":"5","parent_id":"2","name":"Item-5"},
{"id":"6","parent_id":"2","name":"Item-6"},
{"id":"7","parent_id":"2","name":"Item-7"},
{"id":"8","parent_id":"2","name":"Item-8"},
{"id":"9","parent_id":"2","name":"Item-9"},
{"id":"10","parent_id":"1","name":"Item-2"},
{"id":"11","parent_id":"10","name":"Item-10"},
];
});
有谁能告诉我如何通过递归将这种数组转换为树结构吗?
首先在嵌套数组中递归转换数组
var myApp = angular.module('myApp', []);
myApp.controller('jManajer', function($scope) {
$scope.res = [];
$scope.response = [{
"id": "1",
"parent_id": 0,
"name": "Item-0"
}, {
"id": "2",
"parent_id": "1",
"name": "Item-1"
}, {
"id": "3",
"parent_id": "2",
"name": "Item-3"
}, {
"id": "4",
"parent_id": "2",
"name": "Item-4"
}, {
"id": "5",
"parent_id": "2",
"name": "Item-5"
}, {
"id": "6",
"parent_id": "2",
"name": "Item-6"
}, {
"id": "7",
"parent_id": "2",
"name": "Item-7"
}, {
"id": "8",
"parent_id": "2",
"name": "Item-8"
}, {
"id": "9",
"parent_id": "2",
"name": "Item-9"
}, {
"id": "10",
"parent_id": "1",
"name": "Item-2"
}, {
"id": "11",
"parent_id": "10",
"name": "Item-10"
}, ];
function getNestedChildren(arr, parent) {
var out = []
for (var i in arr) {
if (arr[i].parent_id == parent) {
var children = getNestedChildren(arr, arr[i].id)
if (children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
$scope.res = getNestedChildren($scope.response, "0");
console.log($scope.res);
$scope.nested_array_stingified = JSON.stringify($scope.res);
});
<!DOCTYPE html>
<html>
<head>
<script src="https://code.angularjs.org/1.3.11/angular.js"></script>
</head>
<body ng-app="myApp" ng-controller="jManajer">
{{nested_array_stingified}}
</body>
</html>
之后您可以按照此处的教程进行操作 http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/
在将数据传递到您的视图之前,您需要展开数据。
我稍微修改了你的代码,我也转换了你的数据并将深度和关系字段替换为整数,比较整数比比较字符串和空值更容易。
在这个 example 中,我使用了 Undescore.js 强大的功能来展开数组。
代码可以作为指令中的辅助函数找到:
unflatten = function (array, parent, tree) {
tree = typeof tree !== 'undefined' ? tree : [];
parent = typeof parent !== 'undefined' ? parent : {
id: "0"
};
var children = _.filter(array, function (child) {
return child.parent_id == parent.id;
});
if (!_.isEmpty(children)) {
if (parent.id == "0" || parent.id == null) {
tree = children;
} else {
parent['children'] = children
}
_.each(children, function (child) {
unflatten(array, child)
});
}
console.log(tree)
return tree;
}
如果您想要 VanillaJs 解决方案,请查看此 piece of code
这里还有一个 demo 用您的数据模拟交互式树
下划线unflatten函数被采用from here .
我见过很多将 Json 响应转为 Ul 树结构的答案。 问题是所有这些主题都围绕着一个嵌套的响应指向 parent object 和 child object.
之间的关系我有一个非嵌套的 Json 响应,通过引用 object 来指示关系 属性。
以下为部分回复:
{"id":"1","parent_id":null,"name":"Item-0"}, {"id":"2","parent_id":"1","name":"Item-1"}, {"id":"3","parent_id":"2","name":"Item-2"}, {"id":"4","parent_id":"2","name":"Item-4"}, {"id":"5","parent_id":"2","name":"Item-5"}, {"id":"6","parent_id":"2","name":"Item-6"}, {"id":"7","parent_id":"2","name":"Item-7"}, {"id":"8","parent_id":"2","name":"Item-8"}, {"id":"9","parent_id":"2","name":"Item-9"}, {"id":"10","parent_id":"1","name":"Item-3"}, {"id":"11","parent_id":"10","name":"Item-10"},
您可能已经注意到每个 object 通过 parent_id 与他的父亲联系,parent_id 与他的 parent 的 ID 相关联。
我尝试创建一个自定义指令来读取响应并通过递归构建树结构。
到目前为止我只成功创建了树的第一层。 Demo
app.directive('tree',function(){
var treeStructure = {
restrict: "E",
transclude: true,
root:{
response : "=src",
Parent : "=parent"
},
link: function(scope, element, attrs){
var log = [];
scope.recursion = "";
angular.forEach(scope.response, function(value, key) {
if(value.parent_id == scope.Parent){
this.push(value);
}
}, log);
scope.filteredItems = log;
scope.getLength = function (id){
var test = [];
angular.forEach(scope.response, function(value, key) {
if(value.parent_id == id){
this.push(value);
}
}, test);
if(test.length > 0){
scope.recursion = '<tree src="scope.response" parent="'+id+'"></tree>';
}
return scope.recursion;
};
},
template:
'<ul>'
+'<li ng-repeat="item in filteredItems">'
+'{{item.name}}<br />'
+'{{getLength(item.id)}}'
+'</li>'
+'<ul>'
};
return treeStructure;
});
app.controller('jManajer', function($scope){
$scope.information = {
legend : "Angular controlled JSon response",
};
$scope.response = [
{"id":"1","parent_id":null,"name":"Item-0"},
{"id":"2","parent_id":"1","name":"Item-1"},
{"id":"3","parent_id":"2","name":"Item-3"},
{"id":"4","parent_id":"2","name":"Item-4"},
{"id":"5","parent_id":"2","name":"Item-5"},
{"id":"6","parent_id":"2","name":"Item-6"},
{"id":"7","parent_id":"2","name":"Item-7"},
{"id":"8","parent_id":"2","name":"Item-8"},
{"id":"9","parent_id":"2","name":"Item-9"},
{"id":"10","parent_id":"1","name":"Item-2"},
{"id":"11","parent_id":"10","name":"Item-10"},
];
});
有谁能告诉我如何通过递归将这种数组转换为树结构吗?
首先在嵌套数组中递归转换数组
var myApp = angular.module('myApp', []);
myApp.controller('jManajer', function($scope) {
$scope.res = [];
$scope.response = [{
"id": "1",
"parent_id": 0,
"name": "Item-0"
}, {
"id": "2",
"parent_id": "1",
"name": "Item-1"
}, {
"id": "3",
"parent_id": "2",
"name": "Item-3"
}, {
"id": "4",
"parent_id": "2",
"name": "Item-4"
}, {
"id": "5",
"parent_id": "2",
"name": "Item-5"
}, {
"id": "6",
"parent_id": "2",
"name": "Item-6"
}, {
"id": "7",
"parent_id": "2",
"name": "Item-7"
}, {
"id": "8",
"parent_id": "2",
"name": "Item-8"
}, {
"id": "9",
"parent_id": "2",
"name": "Item-9"
}, {
"id": "10",
"parent_id": "1",
"name": "Item-2"
}, {
"id": "11",
"parent_id": "10",
"name": "Item-10"
}, ];
function getNestedChildren(arr, parent) {
var out = []
for (var i in arr) {
if (arr[i].parent_id == parent) {
var children = getNestedChildren(arr, arr[i].id)
if (children.length) {
arr[i].children = children
}
out.push(arr[i])
}
}
return out
}
$scope.res = getNestedChildren($scope.response, "0");
console.log($scope.res);
$scope.nested_array_stingified = JSON.stringify($scope.res);
});
<!DOCTYPE html>
<html>
<head>
<script src="https://code.angularjs.org/1.3.11/angular.js"></script>
</head>
<body ng-app="myApp" ng-controller="jManajer">
{{nested_array_stingified}}
</body>
</html>
之后您可以按照此处的教程进行操作 http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/
在将数据传递到您的视图之前,您需要展开数据。 我稍微修改了你的代码,我也转换了你的数据并将深度和关系字段替换为整数,比较整数比比较字符串和空值更容易。
在这个 example 中,我使用了 Undescore.js 强大的功能来展开数组。
代码可以作为指令中的辅助函数找到:
unflatten = function (array, parent, tree) {
tree = typeof tree !== 'undefined' ? tree : [];
parent = typeof parent !== 'undefined' ? parent : {
id: "0"
};
var children = _.filter(array, function (child) {
return child.parent_id == parent.id;
});
if (!_.isEmpty(children)) {
if (parent.id == "0" || parent.id == null) {
tree = children;
} else {
parent['children'] = children
}
_.each(children, function (child) {
unflatten(array, child)
});
}
console.log(tree)
return tree;
}
如果您想要 VanillaJs 解决方案,请查看此 piece of code
这里还有一个 demo 用您的数据模拟交互式树
下划线unflatten函数被采用from here .