Работа с деревьями в angular
Добрый день.
В одном из проектов хочу использовать angular.js, но пока нехватает опыта. Нужно отрисовать json объект, описывающий дерево, с которым пользователь может производить различные манипуляции. Нашел пример отображения дерева с использованием рекурсии: http://jsfiddle.net/fwQBc/1/ Но тут только отрисовка. Как добавить методы для добавления или удаления узлов понять пока не могу. Может кто-то уже сталкивался с подобной задачей и сможет подсказать? Заранее спасибо. |
http://javascript.ru/forum/angular/3...struktury.html
Запусти скрипт, где-то еще были примеры в jsfiddle... найду напишу еще |
Кусок меню, которое сейчас делаю. Добавляются-удаляются пункты, сортируется и проч. Особо не отлаживал, так что буду раз замечаниям и правкам.
Было бы хорошо сделать добавление пунктов в закрытый пункт (В демке jQuery Sortable есть случай, когда элемент на таб перетаскивается, но пока не дошло как это здесь сделать) <!doctype html> <html> <head> <style> ul { list-style: none; padding: 0; margin: 0; } li {background: #888; border: solid 1px red;} li li {background: #aaa;} li li li {background: #eee;} li li li li {background: #fff;} </style> <script src="http://code.jquery.com/jquery-2.0.1.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script> <script src="http://code.angularjs.org/1.1.5/angular.min.js"></script> <script src="http://tamtakoe.ru/angular-ui-sortable.js"></script> <script language="javascript" type="text/javascript"> angular.module('treeMenu', ['ui.sortable']) function TreeCtrl ($scope) { var tree = [{ id: 1, name: "Пункт1", editor: false, res_type: 'page', vis: false, sub: [{ id: 2, name: "Пункт1-1", editor: false, res_type: 'page', vis: false, sub: [] },{ id: 8, name: "Пункт1-2", editor: false, res_type: 'page', vis: false, sub: [] }] },{ id: 5, name: "Пункт2", editor: false, res_type: 'page', vis: false, sub: [] }], blankItem = { id: null, name: '', editor: true, res_type: 'page', vis: false, sub: [] }; /*MainMenu.query(function(data) { tree = one2multi(data); //Преобразование линейного массива в многомерный addBlank(); $scope.tree = tree; menuCollapse(Global.menuItemId) //Активация определенного пункта меню });*/ addBlank(); $scope.tree = tree; menuCollapse(0) //Открытие заданного пункта меню [и закрытие остальных] $scope.open = menuCollapse function menuCollapse (id, accordeon) { var acc = [] function walk(children) { var i = children.length; while (i--) { if (children[i].id == id) { for (var j = 0, n = acc.length; j < n; j++) { acc[j].vis = true } children[i].vis = !children[i].vis } else { if (typeof accordeon === 'undefined' || accordeon === true) children[i].vis = false acc.push(children[i]) walk(children[i].sub) acc.pop() } } } walk(tree); } //Редактирование и добавление элемента $scope.edit = function(item) { item.editor = !item.editor; if (!item.editor) { if (item.id !== null || typeof item.$save == 'function') { //Сохранение console.log(item) /*item.$save();*/ } else { //Добавление /*MainMenu.add(function (data) {*/ var data = { //Якобы полученный пустой новый элемент, созданный на сервере id: 9, name: '', editor: false, res_type: 'page', vis: false, sub: [] } //Находим подмассив в который нужно добавить элемент function walk(children) { var i = children.length; while (i--) { if (children[i] === item) { //Добавляем айдишник и введенный текст в новый элемент и сохраняем var newitem = angular.extend(data, item, {id: data.id}) children.push(angular.copy(blankItem)); children[i] = newitem; /*newitem.$save()*/ console.log(item) sort(); return } else { walk(children[i].sub) } } } walk(tree); /*})*/ } } } //Удаление элемента $scope.del = function (item) { //Находим подмассив из которого нужно удалить элемент function walk(children) { var i = children.length; while (i--) { if (children[i] === item) { /*children[i].$remove(function (data) { sort(); });*/ children.splice(i, 1); sort(); return } else { walk(children[i].sub) } } } walk(tree); /*typeRes[index].vis = false*/ } //Добавление пустых элементов function addBlank () { function walk(children) { var i = children.length; while (i--) { children[i].editor = false; walk(children[i].sub) } children.push(angular.copy(blankItem)); } walk(tree); } //Сохранение порядка элементов $scope.sort = sort; function sort () { var sortArr = [],//айдишники в порядке расположения pidsArr = [] //id-элемента: id-родителя function walk(children, pid) { for (var i = 0, n = children.length; i < n; i++) { if (children[i].id) { sortArr.push(children[i].id) pidsArr.push(pid) walk(children[i].sub, children[i].id); } } } walk($scope.tree, null); /*MainMenu.save({sort: sortArr, pids: pidsArr}, function (data) { })*/ $scope.$$phase || $scope.$apply(); //Если область видимости не находится в фазе digest, запускаем её с помощью $apply(). Делается для того, чтобы информация о сортировке сразу же поступила на сервер. console.log(sortArr) console.log(pidsArr) } } </script> </head> <body ng-app="treeMenu"> <script type="text/ng-template" id="tree_item.html"> <div> <a href="" ng-hide="item.editor" ng-click="open(item.id)"><b>{{item.name}}</b></a> <span ng-show="item.editor"> <input type="text" ng-model="item.name" placeholder="Новый пункт"/> <select ng-model="item.res_type"> <option value="page">страница</option> <option value="catalog">раздел каталога</option> </select> <a href="" ng-click="del(item)">×</a> </span> <a href="" ng-model="item.editor" ng-click="edit(item)">ред./сохр.</a> </div> <ul ui-sortable="{items:'.sortable', connectWith: '.menu', revert: 0, delay: 100, distance: 20, stop: sort}" ng-model="item.sub" ng-show="item.vis" class="menu"> <li ng-repeat="item in item.sub" ng-include="'tree_item.html'" class="sortable"></li> </ul> </script> <div ng-controller="TreeCtrl"> <ul ui-sortable="{items:'.sortable', connectWith: '.menu', revert: 0, delay: 100, distance: 20, stop: sort}" ng-model="tree" class="menu"> <li ng-repeat="item in tree" ng-include="'tree_item.html'" class="sortable"></li> </ul> </div> </body> </html> |
Вот отличный плагин для bootstrap https://github.com/nickperkinslondon...strap-nav-tree
|
Часовой пояс GMT +3, время: 00:48. |