Есть несколько популярных рекурсивных угловых директив Q & A, которые сводятся к одному из следующих решений:
- постепенно компилировать HTML вручную в зависимости от состояния области выполнения
- не используйте директиву вообще, но шаблон <script>, который ссылается на себя
Первая проблема заключается в том, что вы не можете удалить ранее скомпилированный код, если вы не управляете процессом ручной компиляции. Второй подход имеет проблему ... не быть директивой и упускать ее мощные возможности, но, что более важно, его нельзя параметризовать так же, как директиву; это просто связано с новым экземпляром контроллера.
Я играл вручную, выполняя функцию angular.bootstrap
или @compile()
в функции ссылки, но у меня осталась проблема с ручным отслеживанием элементов для удаления и добавления.
Есть ли хороший способ иметь параметризованный рекурсивный шаблон, который управляет добавлением / удалением элементов для отражения состояния времени выполнения? То есть дерево с кнопкой добавления / удаления узла и некоторым полем ввода, значение которого передается по дочерним узлам узла. Возможно сочетание второго подхода с цепочками (но я не знаю, как это сделать)?
источник
compile: function(element) { return RecursionHelper.compile(element); }
наcompile: RecursionHelper.compile
.Добавление элементов вручную и их компиляция - безусловно, идеальный подход. Если вы используете ng-repeat, вам не придется вручную удалять элементы.
Демо: http://jsfiddle.net/KNM4q/113/
источник
Я не знаю наверняка, найдено ли это решение в одном из приведенных вами примеров или в той же базовой концепции, но мне понадобилась рекурсивная директива, и я нашел отличное, простое решение .
Вы должны создать
recursive
директиву и затем обернуть ее вокруг элемента, который делает рекурсивный вызов.источник
[$compile:multidir] Multiple directives [tree, tree] asking for new/isolated scope on: <recursive tree="tree">
compiledContents(scope,function(clone) { iElement.append(clone); });
Иначе, «require» ed контроллер не обрабатывается правильно, и error:Error: [$compile:ctreq] Controller 'tree', required by directive 'subTreeDirective', can't be found!
причина.Начиная с версии Angular 1.5.x трюки больше не требуются, возможно следующее. Больше не нужно грязной работы вокруг!
Это открытие было побочным продуктом моей охоты на лучшее / более чистое решение для рекурсивной директивы. Вы можете найти его здесь https://jsfiddle.net/cattails27/5j5au76c/ . Он поддерживает как 1.3.x.
источник
После использования нескольких обходных путей, я неоднократно возвращался к этой проблеме.
Я не удовлетворен сервисным решением, так как оно работает для директив, которые могут внедрить сервис, но не работает для анонимных фрагментов шаблона.
Точно так же решения, которые зависят от конкретной структуры шаблона путем выполнения DOM-манипуляции в директиве, слишком конкретны и хрупки.
У меня есть то, что я считаю общим решением, которое заключает в себе рекурсию как собственную директиву, которая минимально мешает любым другим директивам и может использоваться анонимно.
Ниже приведена демонстрация, с которой вы также можете поиграть на plnkr: http://plnkr.co/edit/MSiwnDFD81HAOXWvQWIM
источник
Теперь, когда Angular 2.0 вышел в предварительном просмотре, я думаю, что можно добавить альтернативу Angular 2.0. По крайней мере, это пойдет на пользу людям позже:
Ключевой концепцией является создание рекурсивного шаблона с собственной ссылкой:
Затем вы привязываете объект дерева к шаблону и наблюдаете, как рекурсия позаботится обо всем остальном. Вот полный пример: http://www.syntaxsuccess.com/viewarticle/recursive-treeview-in-angular-2.0
источник
Для этого есть действительно очень простой обходной путь, который вообще не требует директив.
Ну, в этом смысле, может быть, это даже не решение исходной проблемы, если вы предполагаете, что вам нужны директивы, но это решение, если вы хотите рекурсивную структуру GUI с параметризованными подструктурами GUI. Что, вероятно, то, что вы хотите.
Решение основано только на использовании ng-controller, ng-init и ng-include. Просто сделайте это следующим образом, предположим, что ваш контроллер называется «MyController», ваш шаблон находится в myTemplate.html и что у вас есть функция инициализации на контроллере, которая называется init, которая принимает аргументы A, B и C, что позволяет параметризовать ваш контроллер Тогда решение выглядит следующим образом:
myTemplate.htlm:
Я обнаружил, по чистой случайности, что такая структура может быть сделана рекурсивной, как вам нравится в простой ванильной форме. Просто следуйте этому шаблону проектирования, и вы можете использовать рекурсивные UI-структуры без каких-либо сложностей с компиляцией и т. Д.
Внутри вашего контроллера:
Единственный недостаток, который я вижу, это неуклюжий синтаксис, с которым вам приходится мириться.
источник
Для этого вы можете использовать угловой рекурсивный инжектор: https://github.com/knyga/angular-recursion-injector
Позволяет делать неограниченную глубину вложенности с кондиционированием. Выполняет перекомпиляцию только при необходимости и компилирует только нужные элементы. Никакой магии в коде.
Одной из вещей, которая позволяет ему работать быстрее и проще, чем другие решения, является суффикс "--recursion".
источник
Я закончил тем, что создал набор основных директив для рекурсии.
IMO Это гораздо более базовое решение, чем найденное здесь, и такое же гибкое, если не больше, поэтому мы не обязаны использовать структуры UL / LI и т. Д. Но, очевидно, они имеют смысл использовать, однако директивы не знают об этом факт...
Супер простой пример будет:
Реализация 'dx-start-with' и 'dx-connect' находится по адресу: https://github.com/dotJEM/angular-tree
Это означает, что вам не нужно создавать 8 директив, если вам нужно 8 различных макетов.
Создать древовидное представление поверх того, где вы можете добавлять или удалять узлы, было бы довольно просто. Как в: http://codepen.io/anon/pen/BjXGbY?editors=1010
С этого момента контроллер и шаблон могут быть обернуты в свою собственную директиву, если захотите.
источник