我得到一个像下面这样的对象:
$scope.Students = [{
"Name": "Muffin 1",
"RollNo": "12312",
"Class": "Standard B",
"Performances": [{
"Group": "Science",
"Subject": "Math",
"Mark": 99
}, {
"Group": "Science",
"Subject": "Physics",
"Mark": 99
}, {
"Group": "Arts",
"Subject": "Drawing",
"Mark": 99
}, {
"Group": "Arts",
"Subject": "Poetry",
"Mark": 99
}]
}, {
"Name": "Muffin 2",
"RollNo": "1232",
"Class": "Standard A",
"Performances": [{
"Group": "Science",
"Subject": "Chemistry",
"Mark": 99
}, {
"Group": "Science",
"Subject": "Physics",
"Mark": 90
}, {
"Group": "Arts",
"Subject": "Drawing",
"Mark": 99
}, {
"Group": "Commerce",
"Subject": "Marketing",
"Mark": 99
}]
}];
我想创建一个这样的表:
Performances.Group
的固定已知值是:科学,艺术或商业但Subject
和Mark
始终是可变的。所以我要做的是将所有主题名称放在左栏中,然后如果学生有该主题的标记,则将其放在学生专栏中。任何人都可以帮我解决这个问题!这是Plunker链接:http://plnkr.co/edit/vvLL00crhwSq4I6pjjUx?p=preview
虽然,我可以按群组过滤所有的表演,但后来我很困惑如何在左栏中包含所有主题名称,然后相应的值,因为它们在单独的数组中。
答案 0 :(得分:1)
首先,您必须在易于模板的结构中重构数据(plunker):
var rows = [[],[],[]]
rows[0].title = 'Student Name';
rows[1].title = 'Roll No';
rows[2].title = 'Class';
var groups = {};
var cols = $scope.Students.length;
angular.forEach($scope.Students , function(student, idx){
rows[0].push(student.Name);
rows[1].push(student.RollNo);
rows[2].push(student.Class);
angular.forEach(student.Performances , function(p) {
// collect groups
groups[p.Group] = groups[p.Group] || {};
// collect subjects per group
groups[p.Group][p.Subject] = groups[p.Group][p.Subject] || Array(cols);
// collect marks per each group subject
groups[p.Group][p.Subject][idx] = p.Mark;
});
});
$scope.rows = rows;
$scope.groups = groups;
然后您可以轻松地迭代这些项目:
<table class="table table-bordered">
<tr ng-repeat="row in rows">
<th>{{row.title}}</th>
<th ng-repeat="cell in row track by $index">{{cell}}</th>
</tr>
<tbody ng-repeat="(group, sections) in groups">
<tr>
<th>Group</th>
<th colspan={{Students.length}}>{{group}}</th>
</tr>
<tr ng-repeat="(section, values) in sections">
<th>{{section}}</th>
<th ng-repeat="value in values track by $index">{{value}}</th>
</tr>
</tbody>
</table>
答案 1 :(得分:1)
这非常符合您的需求:
http://plnkr.co/edit/mvSvBCSowmdKFmprSvBo?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $filter) {
...
$scope.studentsFiltered = $filter('groupByCustom')($scope.Students);
console.log('restructured', $scope.studentsFiltered);
});
现在你想要一种以可重用的方式重组数据的方法,我认为过滤器做得很好。
app.filter('groupByCustom', function(){
return function(studentsList){
console.log('studentsList', studentsList);
// given a list of students, group into classes
// final structure should be object which contains a different nesting
/* we want:
var grouping = {
Science: {
Math: {muffin 1: 99, muffin 2: 99},
Chemistry: {muffin 1: 99, muffin 2: 99}
// null if student is not in class
}
}
*/
var newStructure = {};
angular.forEach(studentsList, function(student, index){
var name = student.Name;
var performances = student.Performances;
angular.forEach(performances, function(perf, ind){
var group = perf.Group;
var mark = perf.Mark;
var sub = perf.Subject;
if(!newStructure[group]){
newStructure[group] = {};
}
if(!newStructure[group][sub]){
newStructure[group][sub] = {};
angular.forEach(studentsList, function(student, index){
if(!newStructure[group][sub][student.name]){
newStructure[group][sub][student.Name] = null;
}
});
}
if(!newStructure[group][sub][name]){
newStructure[group][sub][name] = mark;
}
});
});
angular.forEach(newStructure, function(k,v){
angular.forEach(v, function(k,v){
});
});
// console.log('newStructure', newStructure);
return newStructure;
};
});
然后你可以构建HTML:
<tbody ng-repeat="(group, data) in studentsFiltered">
<tr >
<th class="section">Group</th>
<th class="section" colspan={{Students.length}}>{{group}}</th>
</tr>
<tr ng-repeat="(class, students) in data">
<td>{{class}}</td>
<td ng-repeat="(name, score) in students">{{score}}</td>
</tr>
</tbody>