假设我有一个对象,其中的键对应于与对象相对应的产品和值,而对象又具有与这些产品已售出的价格点相对应的键,以及与销售量相对应的值。
例如,如果我以1美元的价格出售10个小部件,以2美元的价格出售5个小部件,我将拥有数据结构:
{ 'widget': {'1': 10, '2': 5} }
我想循环这个结构并在表格中生成行,例如:
thing price amount
---------------------
widget $1 10
widget $2 5
在Python中,可以将列表推导嵌套到遍历列表这样的数据结构。使用ng-repeat会这样吗?
答案 0 :(得分:18)
这个怎么样?
http://plnkr.co/edit/ZFgu8Q?p=preview
控制器:
$scope.data = {
'widget1': {
'1': 10,
'2': 5
},
'widget2': {
'4': 7,
'6': 6
}
};
查看:
<div ng-controller="MyCtrl">
<table>
<thead>
<tr>
<td>thing</td>
<td>price</td>
<td>amount</td>
</tr>
</thead>
<tbody ng-repeat="(productName, productData) in data">
<tr ng-repeat="(price, count) in productData">
<td>{{productName}}</td>
<td>{{price|currency}}</td>
<td>{{count}}</td>
</tr>
</tbody>
</table>
</div>
输出:
thing price amount
----------------------
widget1 $1.00 10
widget1 $2.00 5
widget2 $4.00 7
widget2 $6.00 6
这将为每个产品输出tbody
(感谢Sebastien C的好主意)。
如果需要,您可以区分第一个,中间和最后一个tbody
(使用ng-repeat
的{{1}},$first
和$middle
)并将其设置为{ {1}}(甚至是$last
等原生CSS选择器 - 我建议使用ng-class
答案 1 :(得分:13)
ng-repeat目前没有一种可能的方法来复制对象内部的迭代(在python中可能的方式)。查看ng-repeat source code并注意匹配的正则表达式是:
(key, value) in collection
- 并且他们会进入密钥数组并分配给值列表,因此您不可能遗憾地拥有复杂的ng-repeat ...
基本上有两种类型的解决方案已经回答:
我认为解决方案2更好,因为我喜欢保持我的排序和放大控制器内部的编码逻辑,而不是在HTML文档中处理它。这也将允许更复杂的排序(即基于价格,金额,widgetName或其他一些逻辑)。
另一件事 - 第二个解决方案将迭代数据集的可能方法(因为那里没有使用 hasOwnProperty )。
我已经改进了 Plunker (基于最后的Plunker)的解决方案,以便使用angular.forEach并显示解决方案相当简单但允许复杂排序逻辑。
$scope.buildData = function() {
var returnArr = [];
angular.forEach($scope.data, function(productData, widget) {
angular.forEach(productData, function( amount, price) {
returnArr.push( {widgetName: widget, price:price, amount:amount});
});
});
//apply sorting logic here
return returnArr;
};
$scope.sortedData = $scope.buildData();
然后在你的控制器中:
<div ng-controller="MyCtrl">
<table>
<thead>
<tr>
<td>thing</td>
<td>price</td>
<td>amount</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in sortedData">
<td>{{ item.widgetName }}</td>
<td>{{ item.price|currency }}</td>
<td>{{ item.amount }} </td>
</tr>
</tbody>
</table>
</div>
答案 2 :(得分:3)
只需将对象转换为数组......在JS中它非常简单。 类似的东西:
$scope.data = { 'widget': { '1': 10, '2': 5 } };
var tableData = [];
for (item in $scope.data) {
var thing = item;
for (subitem in $scope.data[thing]) {
tableData.push({
thing: thing,
price: subitem,
amount: $scope.data[thing][subitem]
});
}
}
我用这个例子创建了一个jsfiddle:http://jsfiddle.net/b7TYf/
答案 3 :(得分:1)
我使用了一个简单的指令,它有一个递归函数来遍历我的嵌套对象并创建嵌套元素。这样就可以保留嵌套的对象结构。
代码:
angular.module('nerd').directive('nestedItems', ['$rootScope', '$compile', function($rootScope, $compile) {
return {
restrict: 'E',
scope: false,
link: function(scope, element, attrs, fn) {
scope.addElement = function(elem, objAr) {
var ulElement = angular.element("<ul></ul>");
if (objAr == undefined || objAr.length == 0) {
return [];
}
objAr.forEach(function(arrayItem) {
var newElement = angular.element("<li>"+arrayItem.val+"</li>");
ulElement.append(newElement);
scope.addElement(newElement,arrayItem.sub);
});
elem.append(ulElement);
};
scope.addElement(element,scope.elements);
}
};
}]);
&#13;
我的对象:
$scope.elements = [
{
id: 1,
val: "First Level",
sub: [
{
id: 2,
val: "Second Level - Item 1"
},
{
id: 3,
val: "Second Level - Item 2",
sub: [{
id: 4,
val: "Third Level - Item 1"
}]
}
]
}
];
&#13;
我的HTML
<nested-items></nested-items>
&#13;