Angular 性能问题、ng-repeat、不需要的回调

Angular performance issues, ng-repeat, unwanted callbacks

我的 angular 应用程序遇到了一些严重的性能问题,这肯定是由于我的 ng-repeat 实施不当,但我不知道如何做得更好。我尝试了其他一些组合,但 none 没有给我想要的结果,也没有更好的性能。由于异步和 $digest 中止,出现了一些无限循环、未定义的变量。 这就是它应该看起来的样子(这就是工作结果,但现在还没有优化):http://scr.hu/0ei9/8bpw9

蓝色单元格的天数 = 用户在场,红色单元格 = 不在。下面是每天的 "shifts"(每个轮班可以在不同的日子完成)。

当我 console.log 某些函数时,它们被调用的次数超出了需要的次数,例如 isPresent (用于检查用户是否将日期提交为可用)被称为 5x180(180 可能是 5 个用户 x 一个月的 30 天)和 getDayOfWeek(在班次行的模板中使用)28+840+812...有 10 个班次.

而我通常只需要为所有单元格调用 isPresent 1x180,为一个班次行调用 getDayOfWeek 1x30 天。也就是说,我真的不明白为什么它被调用了那么多次以及如何优化它。

此外,当我单击蓝色单元格时,会调用 setShift() 函数。我在这里复制了函数但没有分析它,我只是想证明它没有调用任何以前的函数,但是我 console.log 令人印象深刻的 28x "days of the week" + 180 "is present" 和+ 812 "day of the week"。不知道它来自哪里...坦率地说,我点击的所有内容都调用相同的金额 - 如果我更改月份、年份,请单击一个独立按钮...

为了更好地阅读代码,我省略了一些 类 和 css。

感谢您的帮助。

编辑

在对一些代码进行注释和反注释后,我发现当我调用 setShift() 函数时,大部分不需要的日志都来自最后一个子调用:showPopover(),我在其中打开了一个 $modal。评论时,我以前看到的内容只有 1/3。在模态出现之前还有这些东西的其余部分。此外,我认为 temlpateUrl 可能是原因,因为在评论时它不会记录 'is present' 和 'day of week' 的所有那些猎犬。当我点击模态框的任意位置时,它会调用所有这些功能。有任何想法吗?

JS angular 函数

            $scope.isPresent = function(day, month, year, userId) {
              console.log('is present')
              var date = new Date(year, month - 1, day + 1)
              var day = moment(date).format("D-M-YYYY");
              for (var i = 0; i < $scope.presences.length; i++) {
                var presentDay = moment($scope.presences[i].start).format("D-M-YYYY")
                if (presentDay == day && userId == $scope.presences[i].coursierId) {
                  return true
                }
              }
            }

            $scope.getDayOfWeek = function(day, month, year) {
                console.log('day of the week')
                var date = new Date(parseInt(year), month - 1, day + 1)
                var dayId = date.getDay();
                return dayId;
              }
              /*
                used for a limited ng-repeat
              */
            $scope.getTimes = function(n) {
              return new Array(n);
            };


            /*
              Shows a list of sorted out shifts with corresponding
              hours, cities and capabilities of coursier.
            */
            $scope.setShift = function(day, month, year, userId, event) {
              var date = new Date(year, month - 1, day)
              var day = moment(date).format("D-M-YYYY");
              var dayOfWeek = moment(date).day()
                //SORT SHIFTs BY DAY OF WEEK clicked
              var day_shifts = $scope.sortShiftByDayOfWeek(dayOfWeek)
                //console.log(day_shifts)
                //check if the day clicked is an dispo present day
              for (var i = 0; i < $scope.presences.length; i++) {
                var dispoDay = moment($scope.presences[i].start).format("D-M-YYYY")
                  //if yes, check the presence user id and the cell of user clicked
                if (dispoDay == day) {
                  //then get all the shifts that fit into this coursier's time range
                  if ($scope.presences[i].coursierId == userId) {
                    var dispo = $scope.presences[i];
                    var dispoHours = $scope.getDispoHoursAndDay(dispo);
                    var time_shifts = $scope.compareDiposHoursAndShift(dispoHours, day_shifts);
                    //then sort the shifts by the dispo's and shift's cities
                    var time_city_shifts = $scope.compareDispoCityAndShift(time_shifts, dispo);
                    var time_city_able_shifts = $scope.compareUserAndShift(time_city_shifts, userId);
                    $scope.showPopover(time_city_able_shifts, event);
                  }
                };
              };
            }
###Calendar table
<table class="table table-bordered">
  <!--days of month-->
  <tr class="mainHeader">
    <th>coursier/jour</th>
    ##calendar.days = 30 days of month, for example
    <th class="monthDay" ng-repeat=" numDay in [] | range: calendar.days">{{$index+1}} {{calendar.daysNames[$index]}}
    </th>
  </tr>

  <!-- user name and days -->
  <tr ng-repeat="user in coursiers">
    <!-- <td class="coursierName">nom coursier</td> -->
    <td>
      <a href="#"> {{user.name}}</a> 
    </td>
    <td ng-click="setShift($index+1, monthNum,year, user._id, $event)" ng-repeat="numDay in getTimes(calendar.days) track by $index" ng-class=" isPresent($index, monthNum,year, user._id) == true ?   
           'present' : isAbsent($index, monthNum,year, user._id) == true ?  
           'absent' : '' ">
    </td>
  </tr>

  <tr>
    <td>Shifts par jour</td>
    <td class="shiftsParJourCell" ng-repeat="day in getTimes(calendar.days) track by $index">
      <span ng-repeat="shift in shifts">
                <span ng-repeat="jour in shift.jours">
                  {{jour.id == 
                    getDayOfWeek($parent.$parent.$index, monthNum, year) ? shift.nom : ''}}
                </span>
      </span>
    </td>
  </tr>
</table>

一段时间后,就我而言,问题是我没有使用指令。 范围有不需要的交互(仍然不知道为什么)但是在 angular 指令中分离我的 html 到目前为止没有问题。