AngularJS:遍历嵌套数组 [英] AngularJS: traversing nested arrays
问题描述
我与结构的嵌套数组工作...
I am working with a nested array with the structure...
$scope.items = [{attr1: val1,
attr2: val2,
items: [{
attr1: val1,
attr2: val2,
items: [{
...
}, ...]
}, ...]
}, ...];
该进入一个 NG-重复
与 NG-包括
像这样
<div ng-repeat="item in items" ng-include="'/path/to/template.tpl.html'"></div>
和 template.tpl.html
是
<div>{{item.attr1}}<\div>
<div>{{item.attr2}}<\div>
<div ng-click="fnAddNewItemBelow(item, $parent)"><\div>
<div ng-repeat="item in item.items" ng-include="'/path/to/template.tpl.html'"><\div>
现在,在控制器中,我经常想不喜欢的东西。
Now, in the controller, I commonly want to do things like
- 找到一个项目的父
- 找到一个项目的同级
- 请兄弟姐妹计数
- 找到了多少关卡深的一个项目是嵌套
- 插入或在鸟巢的任何级别删除项目
但我不知道如何优雅地做到这一点。例如,假设我想要实现 fnAddNewItemBelow
。这两个选项我可以工作在
But I'm not sure how to do this elegantly. Eg imagine I wanted to implement fnAddNewItemBelow
. The two options I can work out are
使用嵌套作用域结构角度提供了
Use the nested scopes structure that Angular provides
// pseudo-code only
$scope.fnAddNewItemBelow = function (item, parent) {
var newItem = ...;
// add newItem as a sibling after the item that was ng-clicked
// parent.$parent is necessary because the ng-include adds another scope layer (I think)
parent.$parent.item.items.push(newItem);
// (probably need to use .splice in case there are items after item,
// but I'm keeping it simple)
}
但是,这是丑陋的,因为它假设太多关于结构(如果我把一个NG-如果到&LT; DIV NG点击...
,其中增加了一个范围级别......然后我需要母公司。母公司$,$ parent.item.items.push(的newitem)
)。
But this is ugly because it assumes too much about the structure (what if I put an ng-if onto the <div ng-click...
, which added another scope level... then I'd need parent.$parent.$parent.item.items.push(newItem)
).
另一种方法是直接在 $ scope.items
来操作,因为角将更新用户界面,并与它相关联的作用域。我可以使用循环和一些独特的ID,它有定位项目后,通过 $ scope.items
递归遍历,后插入的newitem它
The alternative is to operate directly on $scope.items
, since Angular will update UI and scopes associated with it. I can iterate recursively through $scope.items
using for loops and after locating item by some unique id that it has, insert newItem after it
// pseudo-code only
$scope.fnAddNewItemBelow = function (item) {
var newItem = ...;
// add newItem as a sibling after the item that was ng-clicked
fnSomeFunctionToFindItemAndInsertItemAfterIt(item.id, newItem);
}
fnSomeFunctionToFindItemAndInsertItemAfterIt (itemId, newItem) {
// fancy recursive function that for loops through each item, and calls
// itself when there are children items. When it finds item with itemId, it
// splices in the newItem after
}
,因为它需要迭代通过整个项目树我想要做的嵌套数组的东西每次我不喜欢这样。
I don't like this because it requires iterating through the entire items tree every time I want to do something with the nested array.
是否有更优雅的解决方案?
Are there more elegant solutions?
推荐答案
如果您别名 item.items
在 NG-重复
前pression,角度会跟踪阵列结构和层次关系你。
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);
}
要得到兄弟姐妹的数量,你可以参考 items.length
:
To get the number of siblings, you can refer to items.length
:
<h3>Item #{{$index + 1}} of {{items.length}}</h3>
如果你真的需要从子项访问父兄弟姐妹,你可以添加其他别名父=项
,并使用 NG-INIT
:
ng-repeat="item in items = (parent = item).items" ng-init="item.parent = parent"
然后,你可以访问祖父母( parent.parent
)和及其项目(父兄弟姐妹)。
Then you have access to the grandparent (parent.parent
) and its items
(the parent siblings).
此外,您可以使用跟踪当前嵌套级别的 NG-INIT
:
In addition, you can keep track of the current nest level using ng-init
:
ng-init="item.parent = parent; item.level = parent.level + 1"
下面是一个工作演示: http://plnkr.co/xKSwHAUdXcGZcwHTDmiv
Here is a working demo: http://plnkr.co/xKSwHAUdXcGZcwHTDmiv
这篇关于AngularJS:遍历嵌套数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!