рекурсивный и бесконечный ng-повтор

#angularjs

#angularjs

Вопрос:

Я хотел бы создать, возможно, бесконечное дерево div.

Это то, что я на самом деле делаю :

 <div ng-repeat="block in blocks">
    <p class="blocke" > {{block.title}} </p>
    <input class="childButton" ng-model="childName[$index]" type="text" placeholder="child name">
    <button class="childButton" ng-click="addChild($index)" >Add child to {{block.title}} </button>
</div>
 

но каждый блок в блоках имеет массив дочерних блоков и так далее.

Я хотел бы создать тот же div, что и выше, для каждого существующего блока. На любом уровне.

Есть ли простой способ сделать это?

Ответ №1:

Создайте пользовательскую директиву, которая вызывает себя, если есть дочерние элементы. Это, с некоторым редактированием, должно работать:

 app.directive('block', ['$compile', function ($compile) {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      block: '='
    },
    template: '<div>'  
      '<p class="blocke"> {{block.title}} </p>'  
      '<input class="childButton" ng-model="childName[$index]" type="text" placeholder="child name">'  
      '<button class="childButton" ng-click="addChild($index)" >Add child to {{block.title}} </button>'  
    '</div>',
    link: function($scope, $element) {
      if (angular.isArray($scope.block.childs) amp;amp; $scope.block.childs.length > 0) {
        $element.append('<block ng-repeat="childBlocks in block.childs" block="childBlocks"></block>');
        $compile($element.contents().last())($scope);
      }
    }
  };
}]);
 

использование <block ng-repeat="block in blocks" block="block></block>

Как это работает: директива заменяет ваши элементы в представлениях шаблоном директивы, затем проверяет, есть ли дочерние элементы для элемента блока, если да, добавляет элемент блока (сама директива) и компилирует его.

Этот конкретный код не был протестирован, но именно так я поступил в аналогичной ситуации.

Комментарии:

1. Я приблизительно понимаю эту директиву, но есть одна проблема. По крайней мере, для меня это проблема. В функции link вы проверяете, является ли $scope.block.childs массивом, но у меня есть массив блоков, подобных этому $scope.block=[{‘title’:»,’childs’:[]}] например. Поэтому мне нужно проверить $scope.block[index].childs. Как мне это сделать, с каким индексом?

2. В этом случае вам не нужны индексы. При использовании этой директивы с ng-repeat="block in blocks" вами также передается текущий элемент блока через block="block" атрибут, поэтому каждый раз, когда вызывается директива, это другой блок $scope.block1 (в первый раз это блок [0], затем блок [1] и так далее.)

3. хорошо. но этот $scope.block никогда не устанавливается … поскольку у нас есть block : ‘=’ (я действительно не знаю, что это значит), а затем block=»Дочерний блок», который, я полагаю, представляет собой массив блоков в каждом блоке, но при первом вызове функции $scope.childs являетсяне определено, и поэтому я не могу вызвать $scope.block.childs

4. $scope.block задается атрибутом элемента block="block" . block: '=' эквивалентно block: '=block' , это означает, что $scope.block будет иметь значение, которое задано в атрибуте элемента с именем block (mindblowing .. Я знаю ..). В первый раз это вызывается из вашего представления, и если переданный атрибут имеет дочерние элементы, добавляется другая директива, а дочерние блоки повторяются и передаются как block , поэтому создается совершенно другая область, где block="childBlocks" равно $scope.block

5. Кажется, все работает отлично, за исключением того, что дочерние блоки не отображаются. Дерево построено так, как я хочу, но отображается только корневой уровень. Проблема связана с тем, что функция, определенная в ‘link’, вызывается только после создания нового блока, а не при добавлении дочернего блока