Angular ng-repeat 嵌套 json 对象?
Angular ng-repeat with nested json objects?
我有一个 JSON 对象,表示为:
{
"orders" : [
{
"ordernum" : "PRAAA000000177800601",
"buyer" : "Donna Heywood"
"parcels" : [
{
"upid" : "UPID567890123456",
"tpid" : "TPID789456789485"
},
{
"upid" : "UPID586905486090",
"tpid" : "TPID343454645455"
}
]
},
{
"ordernum" : "ORAAA000000367567345",
"buyer" : "Melanie Daniels"
"parcels" : [
{
"upid" : "UPID456547347776",
"tpid" : "TPID645896579688"
},
{
"upid" : "UPID768577673366",
"tpid" : "TPID784574333345"
}
]
}
]
}
我需要在 第二层 上做一个转发器,"upid" 号码列表。
我已经知道如何获得顶级
<li ng-repeat="o in orders">{{o.ordernum}}</li>
但我不清楚循环下一级的顺序。例如,这是错误的:
<li ng-repeat="p in orders.parcels">{{p.upid}}</li>
我也知道如何嵌套中继器来获得这个,但在这种情况下我根本不需要显示顶层。
澄清
这里的目标是得到一个包含 4 个 "upid" 编号的列表(每个包裹有 2 个,订单中有 2 个包裹)。
看来您只需要一个双嵌套 for 循环 -
<ul>
<div ng-repeat="o in orders">
<li ng-repeat="p in o.parcels">{{p.upid}}</li>
</div>
</ul>
HTML 在这里可能有点难看,但我不确定您到底要做什么。或者,您可以通过映射创建 parcels
的新数组。
您可以像下面的演示一样创建新数组 'parcels':
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
$scope.data = {
"orders": [{
"ordernum": "PRAAA000000177800601",
"buyer": "Donna Heywood",
"parcels": [{
"upid": "UPID567890123456",
"tpid": "TPID789456789485"
}, {
"upid": "UPID586905486090",
"tpid": "TPID343454645455"
}]
}, {
"ordernum": "ORAAA000000367567345",
"buyer": "Melanie Daniels",
"parcels": [{
"upid": "UPID456547347776",
"tpid": "TPID645896579688"
}, {
"upid": "UPID768577673366",
"tpid": "TPID784574333345"
}]
}]
};
$scope.parcels = [];
angular.forEach($scope.data.orders, function(order) {
angular.forEach(order.parcels, function(parcel) {
$scope.parcels.push(parcel)
})
})
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<ul>
<li ng-repeat="o in parcels">{{o.upid}}</li>
</ul>
</div>
</div>
<li ng-repeat="p in orders.parcels">{{p.upid}}</li>
无法按您预期的方式工作的原因是因为包裹数组是订单数组中每个单独订单内的对象,即它不是订单数组本身的对象。
如果您的订单数组是在控制器的 $scope 上定义的,那么您可以在 $scope
变量上创建数组:
$scope.allParcels = $scope.orders
.map(function (elem) {
return elem.parcels;
}) // get an array where each element is an array of parcels.
.reduce(function (previousValue, currentValue) {
return previousValue.concat(currentValue);
}); // concat each array of parcels into a single array of parcels
然后在模板上,您可以使用<li ng-repeat='p in allParcels'>{{p.upid}}</li>
但是,如果您不想将数组放在 $scope
上,我相信您可以执行类似的操作:
<li ng-repeat="p in orders
.map(function (elem) {
return elem.parcels;
})
.reduce(function (previousValue, currentValue) {
return previousValue.concat(currentValue);
})">{{p.upid}}</li>
尽管我不是 100% 确定 Angular 会计算 ng-repeat
表达式中的 .map/.reduce(也在 ng-repeat
中以这种方式生成一个数组这是不明智的,因为 angular 必须在每个 $digest
周期通过 map/reduce 不断生成一个新数组。
实际上与@sylwester 的回答相同。更好的方法是把它放在 filter
中。您可以通过传递 propertyName 参数来重用它。
在你的情况下,我们通过了 parcels
JS
myApp.filter('createarray', function () {
return function (value, propertyName) {
var arrayList = [];
angular.forEach(value, function (val) {
angular.forEach(val[propertyName], function (v) {
arrayList.push(v)
});
});
return arrayList;
}
});
HTML
<ul>
<li ng-repeat="o in ordersList.orders | createarray: 'parcels'">{{o.upid}}</li>
</ul>
正在大量搜索用于动态迭代的简单好用的解决方案。我想到了这个
JAVASCRIPT(angular):一个人是嵌套对象的一个例子。 is_object 函数将在 HTML 视图中使用。
$scope.person = {
"name": "john",
"properties": {
"age": 25,
"sex": "m"
},
"salary": 1000
}
// helper method to check if a field is a nested object
$scope.is_object = function (something) {
return typeof (something) == 'object' ? true : false;
};
HTML:为简单的table定义一个模板。第一个 TD 是显示的键。如果另一个 TD(2 或 3,但绝不会同时出现)将显示该值,如果它不是对象(数字/字符串),或者如果它是对象,则再次循环。
<table border="1">
<tr ng-repeat="(k,v) in person">
<td> {{ k }} </td>
<td ng-if="is_object(v) == false"> {{ v }} </td>
<td ng-if="is_object(v)">
<table border="1">
<tr ng-repeat="(k2,v2) in v">
<td> {{ k2 }} </td>
<td> {{ v2 }} </td>
</tr>
</table>
</td>
</tr>
</table>
我有一个 JSON 对象,表示为:
{
"orders" : [
{
"ordernum" : "PRAAA000000177800601",
"buyer" : "Donna Heywood"
"parcels" : [
{
"upid" : "UPID567890123456",
"tpid" : "TPID789456789485"
},
{
"upid" : "UPID586905486090",
"tpid" : "TPID343454645455"
}
]
},
{
"ordernum" : "ORAAA000000367567345",
"buyer" : "Melanie Daniels"
"parcels" : [
{
"upid" : "UPID456547347776",
"tpid" : "TPID645896579688"
},
{
"upid" : "UPID768577673366",
"tpid" : "TPID784574333345"
}
]
}
]
}
我需要在 第二层 上做一个转发器,"upid" 号码列表。
我已经知道如何获得顶级
<li ng-repeat="o in orders">{{o.ordernum}}</li>
但我不清楚循环下一级的顺序。例如,这是错误的:
<li ng-repeat="p in orders.parcels">{{p.upid}}</li>
我也知道如何嵌套中继器来获得这个,但在这种情况下我根本不需要显示顶层。
澄清
这里的目标是得到一个包含 4 个 "upid" 编号的列表(每个包裹有 2 个,订单中有 2 个包裹)。
看来您只需要一个双嵌套 for 循环 -
<ul>
<div ng-repeat="o in orders">
<li ng-repeat="p in o.parcels">{{p.upid}}</li>
</div>
</ul>
HTML 在这里可能有点难看,但我不确定您到底要做什么。或者,您可以通过映射创建 parcels
的新数组。
您可以像下面的演示一样创建新数组 'parcels':
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
$scope.data = {
"orders": [{
"ordernum": "PRAAA000000177800601",
"buyer": "Donna Heywood",
"parcels": [{
"upid": "UPID567890123456",
"tpid": "TPID789456789485"
}, {
"upid": "UPID586905486090",
"tpid": "TPID343454645455"
}]
}, {
"ordernum": "ORAAA000000367567345",
"buyer": "Melanie Daniels",
"parcels": [{
"upid": "UPID456547347776",
"tpid": "TPID645896579688"
}, {
"upid": "UPID768577673366",
"tpid": "TPID784574333345"
}]
}]
};
$scope.parcels = [];
angular.forEach($scope.data.orders, function(order) {
angular.forEach(order.parcels, function(parcel) {
$scope.parcels.push(parcel)
})
})
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<ul>
<li ng-repeat="o in parcels">{{o.upid}}</li>
</ul>
</div>
</div>
<li ng-repeat="p in orders.parcels">{{p.upid}}</li>
无法按您预期的方式工作的原因是因为包裹数组是订单数组中每个单独订单内的对象,即它不是订单数组本身的对象。
如果您的订单数组是在控制器的 $scope 上定义的,那么您可以在 $scope
变量上创建数组:
$scope.allParcels = $scope.orders
.map(function (elem) {
return elem.parcels;
}) // get an array where each element is an array of parcels.
.reduce(function (previousValue, currentValue) {
return previousValue.concat(currentValue);
}); // concat each array of parcels into a single array of parcels
然后在模板上,您可以使用<li ng-repeat='p in allParcels'>{{p.upid}}</li>
但是,如果您不想将数组放在 $scope
上,我相信您可以执行类似的操作:
<li ng-repeat="p in orders
.map(function (elem) {
return elem.parcels;
})
.reduce(function (previousValue, currentValue) {
return previousValue.concat(currentValue);
})">{{p.upid}}</li>
尽管我不是 100% 确定 Angular 会计算 ng-repeat
表达式中的 .map/.reduce(也在 ng-repeat
中以这种方式生成一个数组这是不明智的,因为 angular 必须在每个 $digest
周期通过 map/reduce 不断生成一个新数组。
实际上与@sylwester 的回答相同。更好的方法是把它放在 filter
中。您可以通过传递 propertyName 参数来重用它。
在你的情况下,我们通过了 parcels
JS
myApp.filter('createarray', function () {
return function (value, propertyName) {
var arrayList = [];
angular.forEach(value, function (val) {
angular.forEach(val[propertyName], function (v) {
arrayList.push(v)
});
});
return arrayList;
}
});
HTML
<ul>
<li ng-repeat="o in ordersList.orders | createarray: 'parcels'">{{o.upid}}</li>
</ul>
正在大量搜索用于动态迭代的简单好用的解决方案。我想到了这个
JAVASCRIPT(angular):一个人是嵌套对象的一个例子。 is_object 函数将在 HTML 视图中使用。
$scope.person = {
"name": "john",
"properties": {
"age": 25,
"sex": "m"
},
"salary": 1000
}
// helper method to check if a field is a nested object
$scope.is_object = function (something) {
return typeof (something) == 'object' ? true : false;
};
HTML:为简单的table定义一个模板。第一个 TD 是显示的键。如果另一个 TD(2 或 3,但绝不会同时出现)将显示该值,如果它不是对象(数字/字符串),或者如果它是对象,则再次循环。
<table border="1">
<tr ng-repeat="(k,v) in person">
<td> {{ k }} </td>
<td ng-if="is_object(v) == false"> {{ v }} </td>
<td ng-if="is_object(v)">
<table border="1">
<tr ng-repeat="(k2,v2) in v">
<td> {{ k2 }} </td>
<td> {{ v2 }} </td>
</tr>
</table>
</td>
</tr>
</table>