以下是样本plunker http://embed.plnkr.co/bJFmT0WlRfqUgrCxZRT6
首先:我正在按某个键对一个集合进行分组 - 在我的示例yob中。
我有两个选择 -
所以我决定尝试这两种方法 - 使用lodash我用一个键对集合进行分组并显示输出(参见plunkr)
当我在这种情况下使用自定义方法studentsByYear
时,不知何故,数组在显示之前变为空。我有控制台在返回数组之前记录了我的输出,并且数组具有所需的输出..
所以我的问题是为什么我的分组方法不起作用?我错过了有棱角的东西吗?在返回之前我是否必须对对象进行深层复制,如果是,请解释一下吗?
<div ng-controller="myController">
<h2> Using Lodash </h2>
<ul ng-repeat="(yob, students) in myModel.studentsByYobLodash">
<h3>{{ yob }}</h3>
<div ng-repeat="s in students">
<p> {{s.name}} </p>
</div>
</ul>
<h2>Not using Lodash </h2>
<ul ng-repeat="(yob, students) in myModel.studentsByYob">
<h3>{{ yob }}</h3>
<div ng-repeat="s in students">
<p> {{s.name}} </p>
</div>
</ul>
</div>
var app = angular.module("myApp", []);
app.factory('studentsFactory', [function () {
var students = [{
name: 'Tony',
yob: '1987'
},{
name: 'Rachel',
yob: '1988'
}, {
name: 'Eric',
yob: '1988'
}, {
name: 'Jon',
yob: '1988'
}, {
name: 'Tim',
yob: '1989'
}, {
name: 'Bing',
yob: '1987'
}, {
name: 'Valerie',
yob: '1988'
}, {
name: 'Brandon',
yob: '1987'
}, {
name: 'Sam',
yob: '1987'
}]
return {
getStudents: function () {
return students;
}
}
}])
app.controller('myController', ['$scope', 'studentsFactory', function ($scope, studentsFactory) {
$scope.myModel = [];
$scope.myModel.students = studentsFactory.getStudents();
$scope.myModel.studentsByYobLodash = studentsByYearUsingLodash($scope.myModel.students)
$scope.myModel.studentsByYob = studentsByYear($scope.myModel.students);
function studentsByYearUsingLodash (students) {
return _.groupBy(students, 'yob');
}
function studentsByYear(students) {
var arr = [];
angular.forEach(students, function (student) {
var key = student.yob;
_.has(arr, key) ? arr[key].push(student) : (arr[key] = [student]);
})
return arr;
}
}])
答案 0 :(得分:2)
使用结构,您在ng-repeat中使用key, value
对象迭代。因此,通过发送myModel.studentsByYob
作为数组将最终返回一个带孔的数组,因为你最终会将myModel.studentsByYob [0 ..]视为未定义,因为它们不存在而且数组对象改为有属性1987,1988等指向学生阵列,如果你检查浏览器控制台,你会看到ng-repeat代码指向的完全相同的错误,因为返回了多个未定义的键。所以只需改变:
var arr = [];
到
var arr = {};
答案 1 :(得分:1)
问题是您在arr
中创建studentsByYear()
:
var arr = [];
应该是
var arr = {};
Angular迭代器以不同方式处理数组和对象,因此在非零索引数组上进行迭代时,使用(key,value)将始终导致未设置的键。由于Angular认为undefined == undefined
,因此会导致重复的密钥错误。
顺便说一句:你理论上可以完全避开这个错误一次,所以如果你的yob是:
[1, 2, 3, 4...] instead of [1987, ...]
你不会有错误,只是列表顶部的空“0”。
http://plnkr.co/edit/VPiJSjOqPNFeunc7LUqJ?p=preview
但是一旦你有2个无序索引
[2, 3, 4...] // 0 and 1 are missing
然后您将再次收到错误,因为0 == undefined
和1 == undefined
因此0 == 1
,这是一个重复的错误。