Angularjs AngularUI日历事件源,在每个视图开关上调用函数

Angularjs AngularUI日历事件源,在每个视图开关上调用函数,angularjs,fullcalendar,angular-ui,Angularjs,Fullcalendar,Angular Ui,为了演示这个问题,我将解释我试图实现的目标。我正在使用AngularUI Calendar创建一个预订系统,问题是当事件数量增加时(100多个事件,日历将需要几分钟来绑定数据),日历的性能开始迅速显著下降。由于我试图在视图更改时从后端获取数据,每次用户更改视图(周、月、日、上一次、下一次……等等)时都发送AJAX请求,这就是我开始遇到问题的时候 正如网站上建议的那样,我可以使用这个函数:$scope.eventsF=函数(开始、结束、时区、回调){…}并将其添加到$scope.eventSour

为了演示这个问题,我将解释我试图实现的目标。我正在使用AngularUI Calendar创建一个预订系统,问题是当事件数量增加时(100多个事件,日历将需要几分钟来绑定数据),日历的性能开始迅速显著下降。由于我试图在视图更改时从后端获取数据,每次用户更改视图(周、月、日、上一次、下一次……等等)时都发送AJAX请求,这就是我开始遇到问题的时候

正如网站上建议的那样,我可以使用这个函数:
$scope.eventsF=函数(开始、结束、时区、回调){…}
并将其添加到
$scope.eventSources
中,它将在每个视图开关上被调用。我将
$scope.eventsF
添加到我的
$scope.eventSources
中,但它从未更新过

以下是示例(正在获取所有数据,并且正在运行):

现在,我更改了
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.eventSources
的末尾将事件源重新分配给
$scope.eventsF
。下面的代码基于您的第二个选项。干杯

$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.mainEvents=[];
$scope.draftEvents=[];
$scope.eventsF=函数(开始、结束、时区、回调){
var s=start.format('YYYY-MM-DD'),
e=结束格式('YYYY-MM-DD');
获取事件(s,e)。然后(函数(事件){
$scope.mainEvents=[];
如果(事件){
角度.forEach(事件、函数(值){
这个。推(值);
},$scope.mainEvents);
//重新分配事件源
$scope.eventSources=[$scope.mainEvents、$scope.draftEvents、$scope.eventsF];
//假设“事件”是一个包含5个元素的数组。
//console.log($scope.eventSources)将生成:

//数组[Array[5]、数组[0]、应用程序我猜这是由Javascript的变量作用域引起的。您在不同的作用域中引用了
$scope.eventSources
,而不是控制器中的
$scope.eventSources
。可能
$scope.eventSources
会被复制到中的某个地方

只需创建一个包含变量引用的变量,即可访问控制器中的
$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);
  });
};

如果我理解正确的话-添加100个事件,而只显示10个会导致问题?这有点奇怪…不,您错过了AngularUI日历的主要目的,即保持监视事件以进行更改(数据绑定)。我的意思是当
$scope.eventSources
包含100个事件时(无论它们是否已添加或修改),性能都会下降,这也是因为
$scope
正在监视这些事件的更改(标题、开始时间、结束时间等的更改)如果您试图在angularUiCalendar供应商的网站上向示例添加100多个事件。这是怎么回事?我已经更新了答案,以澄清我在哪个部分测试了
$scope.eventSources
。您能告诉我您想在代码的哪个部分测试
$scope.eventSources
?干杯。我正在使用
ngInspector
,但是您可以在HTML中绑定
$scope.eventSources
,以确保它得到更新(我知道这不是测试的最佳方法,但它在调试时工作得很好),就像这样
{eventSources | json}
谢谢您的回答,但是,我认为这不是问题所在(可以访问
$scope.eventSources
,整个逻辑取决于此)。正如我在问题中提到的,
回调
方法基本上是在日历上呈现事件,而不是更新
$scope.mainEvents
$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);
  });
};