#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’, вызывается только после создания нового блока, а не при добавлении дочернего блока