在每个视图切换时调用函数的 AngularUI 日历事件源
AngularUI Calendar event source that calls a function on every view switch
为了演示问题,我将解释我要实现的目标。我正在使用 AngularUI 日历创建一个预订系统,问题是当事件数量增加时(100 多个事件,日历将需要几分钟才能绑定数据),日历的性能开始下降得非常快且明显。因此,我试图在每次用户更改视图(周、月、日、上一个、下一个...等)时发送 AJAX 请求,从而在视图更改时从后端获取数据。这是当我开始有问题时。
正如 AngularUI Calendar 网站上所建议的那样,我可以使用此功能:$scope.eventsF = function (start, end, timezone, callback) {...}
并将其添加到 $scope.eventSources
并且它会在每次视图切换时调用。我将 $scope.eventsF
添加到我的 $scope.eventSources
,但它从未更新过。
这是示例(获取所有数据,并且它正在运行):
$scope.mainEvents = []; //To initiate the event source
Event.getEvents().then(function (events) { // Event is a factory
if (events) { //Checking if I have events
// If I try: $scope.mainEvents = events; the $scope.eventSources won't update
angular.forEach(events, function(value) {
this.push(value);
}, $scope.mainEvents);
} else {
// Tell the user no events to render...
}
}, function (error) {
console.log(error);
});
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents];
现在我更改了 Event.getEvents()
以将两个参数作为视图的开始日期和结束日期,将它们发送到后端,并再次以 json 检索数据(工作正常,我安慰出来)。
这是代码(我尝试了两种方法):事件正在渲染,但是 $scope.eventSources
两者都没有更新。
第一个:
$scope.mainEvents = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
$scope.mainEvents = []; //even tried $scope.eventSources.mainEvents
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents); //event tried $scope.eventSources.mainEvents
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents];
第二个:
$scope.eventsF = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
$scope.mainEvents = [];
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
我希望这已经够清楚了。
我能想到的最简单的方法是在 $scope.eventsF
的末尾将事件源重新分配给 $scope.eventSources
。下面的代码基于您的第二个选项。干杯。
$scope.mainEvents = [];
$scope.draftEvents = [];
$scope.eventsF = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
$scope.mainEvents = [];
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
// Re-assign event sources
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
// Assume that 'events' is an array with 5 elements.
// console.log($scope.eventSources) will produce :
// Array [ Array[5], Array[0], app</$scope.eventsF() ]
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
// console.log($scope.eventSources) will produce :
// Array [ Array[0], Array[0], app</$scope.eventsF() ]
编辑
我更新了上面的代码以显示我在哪一部分测试了 $scope.eventSources
。您能否说明您希望 $scope.eventSources
更新示例代码的哪一部分?
我猜这是由 Javascript 的变量范围引起的。您在与控制器中的 $scope.eventSources
不同的范围内引用 $scope.eventSources
。也许 $scope.eventSources
被复制到 AngularUI Calendar.
的某处
您可以在控制器中访问 $scope.eventSources
,只需创建一个包含对变量的引用的变量即可。
// Create a variable that holds reference to controller's $scope
var ctrlScope = $scope;
$scope.mainEvents = [];
$scope.draftEvents = [];
$scope.eventsF = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
// Test
console.log(ctrlScope.eventSources);
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
我找到了解决问题的方法。我不太明白为什么我必须这样做,但我设法让它发挥作用。我已经从 $scope.mainEvents
数组中一个一个地删除事件(我认为在 AngularUI 日历中,他们对每个事件都使用 $watch
),然后将新事件从 promise 添加到 $scope.mainEvents
也一一。 不要使用callback()
函数,因为$scope
会被更新($watch
会负责渲染),所以callback()
将再次呈现该事件,因此您最终将每个事件呈现两次。
这是最终代码:
$scope.mainEvents = [];
$scope.eventsF = function (start, end, timezone, callback) {
//moment.js objects
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
//emptying the array
$scope.mainEvents.splice(0, $scope.mainEvents.length);
//add the retrieved events
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
}, function (error) {
//promise error logic
console.log(error);
});
};
为了演示问题,我将解释我要实现的目标。我正在使用 AngularUI 日历创建一个预订系统,问题是当事件数量增加时(100 多个事件,日历将需要几分钟才能绑定数据),日历的性能开始下降得非常快且明显。因此,我试图在每次用户更改视图(周、月、日、上一个、下一个...等)时发送 AJAX 请求,从而在视图更改时从后端获取数据。这是当我开始有问题时。
正如 AngularUI Calendar 网站上所建议的那样,我可以使用此功能:$scope.eventsF = function (start, end, timezone, callback) {...}
并将其添加到 $scope.eventSources
并且它会在每次视图切换时调用。我将 $scope.eventsF
添加到我的 $scope.eventSources
,但它从未更新过。
这是示例(获取所有数据,并且它正在运行):
$scope.mainEvents = []; //To initiate the event source
Event.getEvents().then(function (events) { // Event is a factory
if (events) { //Checking if I have events
// If I try: $scope.mainEvents = events; the $scope.eventSources won't update
angular.forEach(events, function(value) {
this.push(value);
}, $scope.mainEvents);
} else {
// Tell the user no events to render...
}
}, function (error) {
console.log(error);
});
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents];
现在我更改了 Event.getEvents()
以将两个参数作为视图的开始日期和结束日期,将它们发送到后端,并再次以 json 检索数据(工作正常,我安慰出来)。
这是代码(我尝试了两种方法):事件正在渲染,但是 $scope.eventSources
两者都没有更新。
第一个:
$scope.mainEvents = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
$scope.mainEvents = []; //even tried $scope.eventSources.mainEvents
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents); //event tried $scope.eventSources.mainEvents
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents];
第二个:
$scope.eventsF = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
$scope.mainEvents = [];
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
我希望这已经够清楚了。
我能想到的最简单的方法是在 $scope.eventsF
的末尾将事件源重新分配给 $scope.eventSources
。下面的代码基于您的第二个选项。干杯。
$scope.mainEvents = [];
$scope.draftEvents = [];
$scope.eventsF = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
$scope.mainEvents = [];
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
// Re-assign event sources
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
// Assume that 'events' is an array with 5 elements.
// console.log($scope.eventSources) will produce :
// Array [ Array[5], Array[0], app</$scope.eventsF() ]
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
// console.log($scope.eventSources) will produce :
// Array [ Array[0], Array[0], app</$scope.eventsF() ]
编辑
我更新了上面的代码以显示我在哪一部分测试了 $scope.eventSources
。您能否说明您希望 $scope.eventSources
更新示例代码的哪一部分?
我猜这是由 Javascript 的变量范围引起的。您在与控制器中的 $scope.eventSources
不同的范围内引用 $scope.eventSources
。也许 $scope.eventSources
被复制到 AngularUI Calendar.
您可以在控制器中访问 $scope.eventSources
,只需创建一个包含对变量的引用的变量即可。
// Create a variable that holds reference to controller's $scope
var ctrlScope = $scope;
$scope.mainEvents = [];
$scope.draftEvents = [];
$scope.eventsF = function (start, end, timezone, callback) {
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
if (events) {
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
// Test
console.log(ctrlScope.eventSources);
callback($scope.mainEvents);
}
}, function (error) {
console.log(error);
});
};
$scope.eventSources = [$scope.mainEvents, $scope.draftEvents, $scope.eventsF];
我找到了解决问题的方法。我不太明白为什么我必须这样做,但我设法让它发挥作用。我已经从 $scope.mainEvents
数组中一个一个地删除事件(我认为在 AngularUI 日历中,他们对每个事件都使用 $watch
),然后将新事件从 promise 添加到 $scope.mainEvents
也一一。 不要使用callback()
函数,因为$scope
会被更新($watch
会负责渲染),所以callback()
将再次呈现该事件,因此您最终将每个事件呈现两次。
这是最终代码:
$scope.mainEvents = [];
$scope.eventsF = function (start, end, timezone, callback) {
//moment.js objects
var s = start.format('YYYY-MM-DD'),
e = end.format('YYYY-MM-DD');
Event.getEvents(s, e).then(function (events) {
//emptying the array
$scope.mainEvents.splice(0, $scope.mainEvents.length);
//add the retrieved events
angular.forEach(events, function (value) {
this.push(value);
}, $scope.mainEvents);
}, function (error) {
//promise error logic
console.log(error);
});
};