我在Angular中有以下控制器,它从DB读取一些记录,然后将它们输出到日历中。问题是events数组返回为空。我已经尝试使用$ rootScope.events作为替代,但是这会产生错误“concat不是undefined的函数。”我究竟做错了什么?嵌套作用域有一些诡计吗?
我也刚刚意识到每个活动变量在内部回调中也是未定义的。我认为这是我缺乏的一般知识的一部分。
app.controller('Calendar', ['$scope','$rootScope','$resource','moment', function($scope, $rootScope, $resource ,moment) {
var Activities = $resource('/api/activities');
Activities.query(function(activities){
$rootScope.activities = activities;
//console.log($rootScope.activities);
});
//console.log($rootScope.activities);
var vm = this;
var events = [];
//define the calendar on rootScope, so it has access to the Events data from the other controllers
$rootScope.calendar = new moment();
angular.forEach($rootScope.activities, function(eachActivity){
//console.log(eachActivity.events);
if (eachActivity.events.length > 0){
angular.forEach(eachActivity.events, function(eachEvent, eachActivity){
console.log(eachEvent);
var entry = {
title: eachActivity.title,
type: "warning",
startsAt: eachEvent.startDate,
endsAt: eachEvent.endDate,
incrementBadgeTotal: true
}
events.concat(entry);
});
}
});
vm.events = events;
console.log(vm.events);
vm.calendarView = 'month';
vm.viewDate = moment().startOf('month').toDate();
vm.isCellOpen = true;
}]);
答案 0 :(得分:0)
这里有一些事情发生:
1)concat()方法返回一个新数组,该数组由调用它的数组组成,并与作为参数提供的数组和/或值连接。您需要分配vaues:events = events.concat(entry)
,以便它们在下一次迭代时保留。
2)您已嵌套Angular Loops。通常是必要的,但请注意您的命名约定。
angular.forEach($rootScope.activities, function(eachActivity){
angular.forEach(eachActivity.events, function(eachEvent, eachActivity)
这里你的循环共享相同的参数名称。这是非常不鼓励的,因为它确实会让开发人员试图理解被迭代的对象的范围。我建议确保您的名字始终是唯一且明确的范围。
3)因为你要覆盖你的参数名称,你对title: eachActivity.title
的调用将会查看内部循环第二个参数,在这种情况下是forEach中事件的KEY
循环eachActivity.events对象。键没有属性,它们总是字符串 - 因此你的eachActivity变量已定义,但它没有属性。
我建议改变这些内容,然后根据所取得的进展编辑你的帖子。
答案 1 :(得分:0)
要解决您的问题,请更改
angular.forEach(eachActivity.events, function(eachEvent, eachActivity)
到
angular.forEach(eachActivity.events, function(eachEvent)
第二个参数不是必需的,因为外部循环中已经定义了eachActivity
。
同时将events.concat(entry);
更改为events.push(entry);
此外,不是在$ rootScope上定义日历,而是创建一个日历工厂,并将其注入您需要访问日历数据的控制器中。有许多原因可以解释为什么这样做更好,但最简单的是$ scope不适合在控制器之间共享数据。它们主要用作视图模型,用于在视图和控制器之间绑定数据。
编辑(有关创建工厂的更多详细信息)
您可以像这样定义工厂
app.factory('CalendarService', [function(){
var calendarEvents = []; // or {} or even null depending on how you want to use the variable
return {
calendarEvents : calendarEvents
};
}]);
在你的控制器中,
app.controller('Calendar', ['$scope','$rootScope','$resource','moment', 'CalendarService', function($scope, $rootScope, $resource ,moment, CalendarService) {
...
// instead of $rootScope.calendar = new moment (and I don't understand why you are assigning this to a moment but that's another conversation
CalendarService.calendarEvents = events;
}]);
您需要做的只是将CalendarService
注入您需要使用事件数据的每个控制器,它将在calendarEvents字段中提供。