Можно ли сделать вид дерева с угловым?

Я ищу для отображения данных в древовидной структуре в веб-приложении. Я надеялся использовать Angular для этой задачи.

Похоже, что ng-repeat позволит мне перебирать список узлов, но как я могу затем вложить, когда увеличивается глубина данного узла?

Я попробовал следующий код , но автоматическое экранирование HTML не позволяет этому работать. Кроме того, конечный знак ul находится не в том месте.

Я почти уверен, что эту проблему пойду совершенно неправильно.

Есть идеи?

Посмотрите на эту скрипку

Оригинал: http://jsfiddle.net/brendanowen/uXbn6/8/

Обновлено: http://jsfiddle.net/animaxf/uXbn6/4779/

Это должно дать вам представление о том, как отображать структуру tree like structure используя угловую tree like structure . Это своего рода использование рекурсии в html!

Если вы используете Bootstrap CSS …

Я создал простой повторно используемый элемент управления деревом (директива) для AngularJS на основе списка «nav» Bootstrap. Я добавил дополнительные отступы, значки и анимацию. Для настройки используются атрибуты HTML.

Он не использует рекурсию.

Я назвал его angular-bootstrap-nav-tree (запоминающееся имя, не так ли?)

Здесь есть пример, и источник здесь .

При создании чего-то подобного наилучшим решением является рекурсивная директива. Однако, когда вы делаете такую ​​директиву, вы обнаруживаете, что AngularJS попадает в бесконечный цикл.

Решение для этого – позволить директиве удалять элемент во время события компиляции и вручную компилировать и добавлять их в событиях ссылок.

Я узнал об этом в этой теме и отвлек эту функциональность на службу .

 module.factory('RecursionHelper', ['$compile', function($compile){ return { /** * Manually compiles the element, fixing the recursion loop. * @param element * @param [link] A post-link function, or an object with function(s) registered via pre and post properties. * @returns An object containing the linking functions. */ compile: function(element, link){ // Normalize the link parameter if(angular.isFunction(link)){ link = { post: link }; } // Break the recursion loop by removing the contents var contents = element.contents().remove(); var compiledContents; return { pre: (link && link.pre) ? link.pre : null, /** * Compiles and re-adds the contents */ post: function(scope, element){ // Compile the contents if(!compiledContents){ compiledContents = $compile(contents); } // Re-add the compiled contents to the element compiledContents(scope, function(clone){ element.append(clone); }); // Call the post-linking function, if any if(link && link.post){ link.post.apply(null, arguments); } } }; } }; }]); 

С помощью этой службы вы можете легко создать директиву дерева (или другие рекурсивные директивы). Ниже приведен пример директивы дерева:

 module.directive("tree", function(RecursionHelper) { return { restrict: "E", scope: {family: '='}, template: '

{{ family.name }}

'+ '
    ' + '
  • ' + '' + '
  • ' + '
', compile: function(element) { return RecursionHelper.compile(element); } }; });

См. Этот Plunker для демонстрации. Мне нравится это решение, потому что:

  1. Вам не нужна специальная директива, которая делает ваш html менее чистым.
  2. Логика рекурсии абстрагируется от службы RecursionHelper, поэтому вы сохраняете свои директивы чистыми.

Обновление: добавлена ​​поддержка пользовательских функций связывания.

angular-ui-tree, кажется, делает хорошую работу для меня

Вот пример с использованием рекурсивной директивы: http://jsfiddle.net/n8dPm/ Взято с https://groups.google.com/forum/#!topic/angular/vswXTes_FtM

 module.directive("tree", function($compile) { return { restrict: "E", scope: {family: '='}, template: '

{{ family.name }}

'+ '
    ' + '
  • ' + '' + '
  • ' + '
', compile: function(tElement, tAttr) { var contents = tElement.contents().remove(); var compiledContents; return function(scope, iElement, iAttr) { if(!compiledContents) { compiledContents = $compile(contents); } compiledContents(scope, function(clone, scope) { iElement.append(clone); }); }; } }; });

Это кажется немного более полным: https://github.com/dump247/angular.tree

Другой пример основан на исходном источнике , с уже существующей структурой дерева образцов (проще увидеть, как работает IMO) и фильтром для поиска по дереву:

JSFiddle

Так много отличных решений, но я чувствую, что все они так или иначе слишком усложняют ситуацию.

Я хотел создать что-то, что воссоздало простоту тренда @Mark Lagendijk, но без него определял шаблон в директиве, а скорее позволял бы «пользователю» создавать шаблон в HTML …

С идеями, взятыми из https://github.com/stackfull/angular-tree-repeat и т. Д. … Я закончил создание проекта: https://github.com/dotJEM/angular-tree

Это позволяет вам строить свое дерево как:

 
  • {{ node.name }}

    Который для меня чище, чем создавать несколько директив для разных структурированных деревьев … В сущности, вызывая вышеупомянутое дерево немного ложно, он выбирает гораздо больше от тенера @ ganaraj «рекурсивных шаблонов», но позволяет нам определите шаблон, в котором нам нужно дерево.

    (вы можете сделать это с помощью шаблона, основанного на сценарии, но он все равно должен сидеть прямо за пределами фактического узла дерева, и он все еще просто немного чувствует себя …)

    Остался здесь для другого выбора …

    Вы можете попробовать с образцом Angular-Tree-DnD с Angular-Ui-Tree, но я отредактировал, совместимость с таблицей, сеткой, списком.

    • Able Drag & Drop
    • Расширенная директива функции для списка (next, prev, getChildren, …)
    • Данные фильтра.
    • OrderBy (ver)

    Основываясь на ответе @ganaraj и ответе @ dnc253, я просто сделал простую «директиву» для древовидной структуры, которая имеет возможность выбора, добавления, удаления и редактирования.

    Jsfiddle: http://jsfiddle.net/yoshiokatsuneo/9dzsms7y/

    HTML:

      

    JavaScript:

     angular.module("myApp",[]); /* https://stackoverflow.com/a/14657310/1309218 */ angular.module("myApp"). directive("recursive", function($compile) { return { restrict: "EACM", require: '^tree', priority: 100000, compile: function(tElement, tAttr) { var contents = tElement.contents().remove(); var compiledContents; return function(scope, iElement, iAttr) { if(!compiledContents) { compiledContents = $compile(contents); } compiledContents(scope, function(clone) { iElement.append(clone); }); }; } }; }); angular.module("myApp"). directive("subTree", function($timeout) { return { restrict: 'EA', require: '^tree', templateUrl: 'tree_item_renderer.html', scope: { data: '=', }, link: function(scope, element, attrs, treeCtrl) { scope.select = function(){ treeCtrl.select(scope.data); }; scope.delete = function() { scope.data.parent.nodes.splice(scope.data.parent.nodes.indexOf(scope.data), 1); }; scope.add = function() { var post = scope.data.nodes.length + 1; var newName = scope.data.name + '-' + post; scope.data.nodes.push({name: newName,nodes: [],show:true, parent: scope.data}); }; scope.edit = function(event){ scope.data.editting = true; $timeout(function(){event.target.parentNode.querySelector('input').focus();}); }; scope.unedit = function(){ scope.data.editting = false; }; } }; }); angular.module("myApp"). directive("tree", function(){ return { restrict: 'EA', template: '', controller: function($scope){ this.select = function(data){ if($scope.selected){ $scope.selected.selected = false; } data.selected = true; $scope.selected = data; }; }, scope: { data: '=', } } }); 

    Да, это определенно возможно. Вопрос здесь, вероятно, предполагает Angular 1.x, но для будущей ссылки я включаю в себя пример Angular 2:

    Концептуально все, что вам нужно сделать, это создать рекурсивный шаблон:

     
    • {{ dir.name }}
        {{file}}

    Затем вы привязываете объект дерева к шаблону и позволяете Угловому работать с его магией. Эта концепция, очевидно, применима и к Angular 1.x.

    Вот полный пример: http://www.syntaxsuccess.com/viewarticle/recursive-treeview-in-angular-2.0

    Вы можете использовать угло-рекурсию-инжектор для этого: https://github.com/knyga/angular-recursion-injector

    Позволяет выполнять неограниченную глубину с помощью кондиционирования. Перекомпиляция только при необходимости и компиляция только правильных элементов. Никакой магии в коде.

     
    {{name}}

    Одна из вещей, которая позволяет ему работать быстрее и проще, тогда другие решения – суффикс «-recursion».

    Когда древовидная структура велика, Angular (до 1.4.x) становится очень медленным при рендеринге рекурсивного шаблона. Попробовав ряд этих предложений, я закончил создание простой строки HTML и использовал ng-bind-html для ее отображения. Конечно, это не способ использовать функции Angular

    Здесь показана рекурсивная функция bare-bones (с минимальным HTML):

     function menu_tree(menu, prefix) { var html = '
    ' + prefix + menu.menu_name + ' - ' + menu.menu_desc + '
    \n'; if (!menu.items) return html; prefix += menu.menu_name + '/'; for (var i=0; i

    В шаблоне нужна только одна строка:

     

    Это обходит все привязки данных Angular и просто отображает HTML за небольшую часть времени методов рекурсивных шаблонов.

    С такой структурой меню, как это (частичное дерево файлов файловой системы Linux):

     menu = {menu_name: '', menu_desc: 'root', items: [ {menu_name: 'bin', menu_desc: 'Essential command binaries', items: [ {menu_name: 'arch', menu_desc: 'print machine architecture'}, {menu_name: 'bash', menu_desc: 'GNU Bourne-Again SHell'}, {menu_name: 'cat', menu_desc: 'concatenate and print files'}, {menu_name: 'date', menu_desc: 'display or set date and time'}, {menu_name: '...', menu_desc: 'other files'} ]}, {menu_name: 'boot', menu_desc: 'Static files of the boot loader'}, {menu_name: 'dev', menu_desc: 'Device files'}, {menu_name: 'etc', menu_desc: 'Host-specific system configuration'}, {menu_name: 'lib', menu_desc: 'Essential shared libraries and kernel modules'}, {menu_name: 'media', menu_desc: 'Mount point for removable media'}, {menu_name: 'mnt', menu_desc: 'Mount point for mounting a filesystem temporarily'}, {menu_name: 'opt', menu_desc: 'Add-on application software packages'}, {menu_name: 'sbin', menu_desc: 'Essential system binaries'}, {menu_name: 'srv', menu_desc: 'Data for services provided by this system'}, {menu_name: 'tmp', menu_desc: 'Temporary files'}, {menu_name: 'usr', menu_desc: 'Secondary hierarchy', items: [ {menu_name: 'bin', menu_desc: 'user utilities and applications'}, {menu_name: 'include', menu_desc: ''}, {menu_name: 'local', menu_desc: '', items: [ {menu_name: 'bin', menu_desc: 'local user binaries'}, {menu_name: 'games', menu_desc: 'local user games'} ]}, {menu_name: 'sbin', menu_desc: ''}, {menu_name: 'share', menu_desc: ''}, {menu_name: '...', menu_desc: 'other files'} ]}, {menu_name: 'var', menu_desc: 'Variable data'} ] } 

    Выход будет:

     - root /bin - Essential command binaries /bin/arch - print machine architecture /bin/bash - GNU Bourne-Again SHell /bin/cat - concatenate and print files /bin/date - display or set date and time /bin/... - other files /boot - Static files of the boot loader /dev - Device files /etc - Host-specific system configuration /lib - Essential shared libraries and kernel modules /media - Mount point for removable media /mnt - Mount point for mounting a filesystem temporarily /opt - Add-on application software packages /sbin - Essential system binaries /srv - Data for services provided by this system /tmp - Temporary files /usr - Secondary hierarchy /usr/bin - user utilities and applications /usr/include - /usr/local - /usr/local/bin - local user binaries /usr/local/games - local user games /usr/sbin - /usr/share - /usr/... - other files /var - Variable data 

    Не сложно.

     
    col 1 col 2 col 3
    {{item.id}} {{item.fname}} {{item.lname}}
    {{children.id}} {{children.fname}}

    код controllerа:

     angular.module("myApp", []). controller("TreeController", ['$scope', function ($scope) { $scope.tree = [{ id: 1, fname: "tree", child: [{ id: 1, fname: "example" }], lname: "grid" }]; }]); 
  • Использование углового фильтра в входном элементе
  • Каков наиболее сжатый способ чтения параметров запроса в AngularJS?
  • AngularJS ng-options создают диапазон
  • угловой-ui-маршрутизатор с требованием, ленивая загрузка controllerа
  • Связь с компилятором и controllerом
  • Угловой разрыв JS ForEach
  • AngularJS: $ q -> отложенный API-код вещей (жизненный цикл) И кто вызывает дайджест?
  • AngularJS: ngRoute не работает
  • Асинхронный доступ к массиву в Firebase
  • AngularJS. Преобразование значения тега (время Unix для чтения человеком)
  • Как отправить POST в angularjs с несколькими параметрами?
  • Давайте будем гением компьютера.