Как удалить элемент из древовидной структуры?
Реализация древовидного списка
<!doctype html> <html ng-app="myApp"> <head> <script src="http://code.angularjs.org/1.1.5/angular.min.js"></script> <script> angular.module("myApp", []); function TreeController($scope) { $scope.delAll = function(data) { data.nodes = []; }; $scope.del = function(item) { function walk(children) { var i = children.length; while (i--) { if (children[i] === item) { return children.splice(i, 1); } else { walk(children[i].nodes) } } } walk($scope.nodes); }; $scope.add = function(data) { var newName = data.name + '-' + data.nodes.length + 1; data.nodes.push({name: newName, nodes: []}); }; $scope.nodes = [ {name: 'Узел', nodes: [ {name: 'Морской', nodes: []}, {name: 'Устричный', nodes: []} ]} ]; }; </script> </head> <body> <script type="text/ng-template" id="item.html"> {{data.name}} <button ng-click="add(data)">Добавить потомка</button> <button ng-click="delAll(data)" ng-show="data.nodes.length > 0">Удалить потомков</button> | <button ng-click="add($parent.$parent.$parent.data)">Добавить узел</button> <button ng-click="del(data)">Удалить узел</button> <ul> <li ng-repeat="data in data.nodes" ng-include="'item.html'"></li> </ul> </script> <ul ng-controller="TreeController"> <li ng-repeat="data in nodes" ng-include="'item.html'"></li> </ul> </body> </html> Как реализовать добавление узла к узлу того-же уровня и удаление? Знаю три способа, но все не нравятся. В первом мы передаем (на примере добавления) ссылку на родителя в виде $parent.$parent.$parent, которая еще и зависит от шаблона зависит и нужно добавлять условия для корневых элементов. Во втором — проходимся рекурсией по всей модели, чтобы найти нужный элемент (в примере удаление). По сути, делаем двойную работу и рекурсия в JS имеет ограничения. В третьем — в каждый элемент модели добавляем ссылку на элемент родителя. Не хочется загромождать модель, да и перед сериализацией придется очищать ее от этих ссылок. Что посоветуете? |
Есть четвёртый способ
сделать узел директивой, с изолированным scope, в качестве параметра скармливать только ту область данных на которую узел может влиять. |
Да вот только как это сделать? Дело в том, что узел и так имеет изолированную область видимости. т.к. формируется ng-repeat. Проблема в том, что не получается расширить ng-repeat. Вот тут описаны способы расширения: http://angular.ru/guide/understanding_directives и ни один не подходит. ng-repeat терминальная директива, поэтому всегда выполняется последней и все навешенные после нее директивы просто не будут работать. Можно, конечно, попробовать назвать свою директиву ng-repeat, но как-то стремно делать такое со стандартной директивой...
|
|
Часовой пояс GMT +3, время: 05:13. |