AngularJS: traversing nested arrays

喜你入骨 提交于 2019-12-03 03:41:52

If you alias item.items in the ng-repeat expression, angular will keep track of the array structure and hierarchical relationships for you.

<div ng-repeat="item in items = item.items">

Then, operations on the tree can simply pass in the item, the $index, or the array of items - without knowledge of the full array structure:

  <button ng-click="addItem(item)">Add to my items</button>
  <button ng-click="addSiblingItem(items, $index)">Add a sibling item</button>
  <button ng-click="deleteMe(items, $index)">Delete Me</button>

js:

$scope.addItem = function(item) {
  item.items.push({
    attr1: 'my new - attr1',
    attr2: 'my new - attr2',
    items: []
  });
}
$scope.addSiblingItem = function(items, position) {
  items.splice(position + 1, 0, {
    attr1: 'sibling - new attr1',
    attr2: 'sibling - new attr2',
    items: []
  });
}
$scope.deleteMe = function(items, position) {
  items.splice(position, 1);
}

To get the number of siblings, you can refer to items.length:

<h3>Item #{{$index + 1}} of {{items.length}}</h3>

If you really need to access the parent siblings from child items, you can add another alias for parent = item and add it to the item using ng-init:

ng-repeat="item in items = (parent = item).items" ng-init="item.parent = parent"

Then you have access to the grandparent (parent.parent) and its items (the parent siblings).

In addition, you can keep track of the current nest level using ng-init:

ng-init="item.parent = parent; item.level = parent.level + 1"

Here is a working demo: http://plnkr.co/xKSwHAUdXcGZcwHTDmiv

Before rendering data, you can make some preparations. One recursive run over your data to set level value and a link to the parent to each item. Example with your data using LoDash:

var level = 0;
_.each($scope.items, function(item){recursive(item, level)});

function recursive(item, level){
    item.level = level;
    _.each(item.items, function(innerItem){
        innerItem.parent = item;
        recursive(innerItem, level+1);
    });
}

So now you can easily get parent and siblings of each item.

find an item's parent -> item.parent

find an item's sibling -> item.parent.items[i]

make counts of siblings -> item.parent.items.length

find out how many levels deep an item is nested -> item.level

insert or delete items at any level of the nest (move operation example) ->

newParent.items.push(item);
_.remove(item.parent.items, function(child){return child == item;});

The only minus of this approach which i met - you can not easily clone whole tree without going into endless recursion. But you can make custom cloning function which will not copy links.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!