Это сложная задача для новичка AngularJS, подобного мне, поэтому я хотел бы попросить некоторую помощь или помощь. Поэтому я хочу, чтобы группировать данные через древовидный и древовидный.
Мой текущий код для HTML:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="item in list">
[[ item.code ]]
</li>
</ul>
</div>
</body>
</html>
Мой текущий код для JS:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.list = [
{
"id": 1,
"code": "TANK",
"tree_id": 1,
"level": 0,
"parent": null
},
{
"id": 2,
"code": "OIL",
"tree_id": 1,
"level": 1,
"parent": 1
},
{
"id": 3,
"code": "CHEM",
"tree_id": 1,
"level": 1,
"parent": 1
},
{
"id": 6,
"code": "PROD",
"tree_id": 1,
"level": 2,
"parent": 3
},
{
"id": 4,
"code": "BULK",
"tree_id": 2,
"level": 0,
"parent": null
},
{
"id": 5,
"code": "LOG",
"tree_id": 2,
"level": 1,
"parent": 4
}
],
});
Если вы проверили $ scope.list, вы можете найти tree_id, level и parent. Так что я действительно хочу достичь, чтобы сгруппировать объекты через древовидный идентификатор, тогда уровень 0 или верхний уровень будет тем, который присутствует, тогда как уровень 1 и выше будут просто сбрасываемым контентом. Предположим, что tree_id служит в качестве группировки между объектом, уровень может рассматриваться как их порядок иерархии, а корень иерархии наследников будет зависеть от целочисленного значения родителя, являющегося идентификатором дерева. Также имейте в виду, что это не ограничивается одной ветвью, но несколькими, гибкими и неограниченными ветвями
Результат должен выглядеть примерно так:
Это уже обсуждалось в StackOverFlow. Вы можете использовать следующую ссылку.
Как я могу группировать данные с помощью Углового фильтра?
Используя фильтр groupBy, вы можете получить древовидную структуру.
Вы также можете использовать пользовательские директивы для обработки рекурсивных уровней:
EDIT, чтобы добавить свойства réf в директивы и вашу новую структуру массива
var app = angular.module('myApp', []);
app.directive('collection', function () {
return {
restrict : "E",
replace : true,
transclude: true,
scope : {
collection : '=',
list : '=',
coldisplay : '=',
colfrom : '=',
colto : '='
},
template : "<ul><member ng-repeat='member in collection track by $index' member='member' list='list' coldisplay='coldisplay' colfrom='colfrom' colto='colto'></member></ul>"
};
});
app.directive('member', function ($compile) {
return {
restrict : "E",
replace : true,
transclude: true,
scope : {
member : '=',
list : '=',
coldisplay : '=',
colfrom : '=',
colto : '='
},
template : "<li>{{member[coldisplay]}}</li>",
link : function (scope, element, attrs) {
scope.children = [];
angular.forEach(scope.list, function (value, key) {
if (value[scope.colfrom] === scope.member[scope.colto]) {
this.push(value);
}
}, scope.children);
if (scope.children.length > 0) {
element.append("<collection collection='children' list='list' coldisplay='coldisplay' colfrom='colfrom' colto='colto'></collection>");
$compile(element.contents())(scope);
}
}
}
});
app.controller('myCtrl', function ($scope) {
$scope.list = [{
"id" : 1,
"code" : "TANK",
"tree_id" : 1,
"level" : 0,
"parent" : null
}, {
"id" : 2,
"code" : "OIL",
"tree_id" : 1,
"level" : 1,
"parent" : 1
}, {
"id" : 3,
"code" : "CHEM",
"tree_id" : 1,
"level" : 1,
"parent" : 1
}, {
"id" : 6,
"code" : "PROD",
"tree_id" : 1,
"level" : 2,
"parent" : 3
}, {
"id" : 4,
"code" : "BULK",
"tree_id" : 2,
"level" : 0,
"parent" : null
}
];
$scope.rootList = [];
angular.forEach($scope.list, function (value, key) {
if (value.parent == null) {
this.push(value);
}
}, $scope.rootList);
})
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<collection collection='rootList' list='list' coldisplay='"code"' colfrom='"parent"' colto='"id"'></collection>
</div>
</body>
</html>
Вдохновленный https://toddmotto.com/everything-about-custom-filters-in-angular-js/
чтобы исправить вашу проблему, я бы предложил несколько изменений. Прежде всего, поскольку вы получаете данные из API, нам нужно исправить формат, чтобы получить более разумную структуру. Что-то вроде ниже
[{
id: 1,
code: "TANK",
tree_id: 1,
parent: null,
children: [{
id: 3,
code: "CHEM",
tree_id: 1,
parent: 1,
children: [{
id: 9,
code: "PROD",
tree_id: 1,
parent: 3
}]
}, {
id: 2,
code: "OIL",
tree_id: 1,
parent: 1,
}]
}, {
id: 4,
code: "BULK",
tree_id: 2,
parent: null,
children: [{
id: 5,
code: "LOG",
tree_id: 2,
parent: 4,
}]
}]
Для этого нам нужно написать функцию, как показано ниже
var createObject = function(json) {
return {
id: json.id,
code: json.code,
tree_id: json.tree_id,
parent: json.parent,
children: []
}
};
var processList = function(temporaryObj) {
for (var i = 0; i < list.length; i++) {
if (list[i].parent === temporaryObj.id) {
temporaryObj.children.push(processList(createObject(list[i])));
}
}
return temporaryObj;
};
var convertList = function(list) {
var temp = [];
for (var i = 0; i < list.length; i++) {
if (list[i].level === 0) {
temp.push(processList(createObject(list[i])));
}
}
return temp;
};
var newList = convertList(list_from_api);
И после этого нам нужно создать рекурсивную директиву для печати содержимого в пользовательском интерфейсе
app.directive("tree", ['$compile', '$templateCache', function($compile, $templateCache) {
return {
type: "E",
scope: {
list: "="
},
link: function(scope, element, attrs) {
element.replaceWith( $compile( $templateCache.get('tree.html'))(scope));
}
}
}]);
где tree.html приведен ниже
<ul ng-if="list.length > 0">
<li ng-repeat="item in list">
<span>{{ item.code }}</span>
<tree list="item.children"></tree>
</li>
</ul>
Вы можете обратиться к этой ссылке plunkr для получения более подробной информации https://plnkr.co/edit/8TtgFfgUQd73Du47b7XB?p=preview
в угловой groupBy
Работа для object
не для array
. поэтому вы можете сгенерировать это в своем контроллере по мере необходимости.
Я могу показать вам процесс генерации по вашему желанию. Если хотите, попробуйте.
в вашем контроллере вызовите функцию после получения list
из api.
$scope.newList = {parents:[],childs:[]};
var generateNav = function(parent) {
$scope.newList.parents.push(parent);
angular.forEach($scope.list, function(item) {
if(item.tree_id === parent.tree_id) {
$scope.newList.childs.push(item);
}
})
};
var generateNewList = function(list) {
angular.forEach(list, function(item) {
if(item.level === 0) {
generateNav(item);
}
});
};
// after api cal and get data call this function with your 'list'
generateNewList($scope.list);
и В html: используется newList
<ul>
<li ng-repeat="item in newList.parents">
{{ item.code }}
<ul>
<li ng-repeat="child in newList.childs" ng-if="child.tree_id === item.tree_id && item.id!==child.id">{{child.code}}</li>
</ul>
</li>
</ul>
вы можете посетить PLUNKER DEMO LINK
$scope.list
или использовать существующую структуру?