AngularJS - 减少ng重复次数

时间:2014-10-28 11:50:00

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我有一个注册表,按字母顺序从A到Z列出人员......例如,A先生,每个人都有一组相应的数据Histories

我有一个简单ng-repeat的表格,显示12个单元格的数据(代表12个月)。

如果提供了12个月/单元格的数据,我会显示所有数据,如果只提供了5个月的数据(任何少于12个),我会调用服务srvEmptyCells来计算剩余的单元格和显示颜色较深。

问题是,我注意到我正在重复ng-repeat:

emptyCell in getEmptyCells

多次影响页面性能,因为我有超过100个用户。

有没有办法为每个特定用户保存空单元格的数量?并且不需要额外的ng-repeats?指令会改进吗?

Heres a plunker:http://plnkr.co/edit/2UKDD1fvfYGMjX9oJqVu?p=preview

HTML:

<table ng-repeat="data in myData" class="my-table">
  <caption>
    {{ data.Name }}
  </caption>
  <tbody>
    <tr>
      <th>Rate</th>
      <td ng-repeat="history in data.Histories.slice(0, 12)" class="my-table-cell">
        {{history.Rate}}
      </td>
      <td ng-repeat="emptyCell in getEmptyCells(data.Histories.slice(0, 12).length)" class="empty"></td>
    </tr>
    <tr>
      <th>Effort</th>
      <td ng-repeat="history in data.Histories.slice(0, 12)" class="my-table-cell">
        {{history.Effort}}
      </td>
      <td ng-repeat="emptyCell in getEmptyCells(data.Histories.slice(0, 12).length)" class="empty"></td>
    </tr>
    <tr>
      <th>Advance</th>
      <td ng-repeat="history in data.Histories.slice(0, 12)" class="my-table-cell">
        {{history.Advance}}
      </td>
      <td ng-repeat="emptyCell in getEmptyCells(data.Histories.slice(0, 12).length)" class="empty"></td>
    </tr>
    <tr>
      <th>Previous</th>
      <td ng-repeat="history in data.Histories.slice(0, 12)" class="my-table-cell">
        {{history.Previous}}
      </td>
      <td ng-repeat="emptyCell in getEmptyCells(data.Histories.slice(0, 12).length)" class="empty"></td>
    </tr>
    <tr>
      <th>Current</th>
      <td ng-repeat="history in data.Histories.slice(0, 12)" class="my-table-cell">
        {{history.Current}}
      </td>
      <td ng-repeat="emptyCell in getEmptyCells(data.Histories.slice(0, 12).length)" class="empty"></td>
    </tr>
    <tr>
      <th>Code</th>
      <td ng-repeat="history in data.Histories.slice(0, 12)" class="my-table-cell">
        {{history.Code}}
      </td>
      <td ng-repeat="emptyCell in getEmptyCells(data.Histories.slice(0, 12).length)" class="empty"></td>
    </tr>
  </tbody>
</table>

JS:

app.controller('MainCtrl', function($scope, $http, factoryGetJSONFile, srvEmptyCells) {
  $scope.name = 'World';

  factoryGetJSONFile.getMyData(function(data) {
    $scope.myData = data.MyData.Entries;
  });

  $scope.getEmptyCells = srvEmptyCells.getEmptyCells;

});

app.factory('srvEmptyCells', function() {
    return {
        getEmptyCells: function(len) {
            var emptyCells = [];
            for(var i = 0; i < 12 - len; i++){
                emptyCells.push(i);
            }
            return emptyCells;
        }
     };
 });

2 个答案:

答案 0 :(得分:1)

您可以通过添加$scope.myDatadata.Histories.slice(0, 12)的缓存版本并使用getEmptyCells(data.Histories.slice(0, 12).length)来修改ng-repeat。 通过这种方式,您可以反复重复这些来电。

更好的方法是,如果你可以修改响应,那就是做这个服务端而不是客户端。如果你不需要它们,为什么还要返回超过12个历史?

很难知道这是否会解决您的性能问题,因为每行有多次ng重复,但它会比以前更快。

缓存客户端示例;

factoryGetJSONFile.getMyData(function(data) {
   $scope.myData = data.MyData.Entries;

   for (int i=0; i < $scope.myData.length; i++) {
     var current = $scope.myData[i];
     current.nonEmptyCells = current.Histories.slice(0, 12);
     current.emptyCells =  srvEmptyCells.getEmptyCells(current.nonEmptyCells.length);
   }
});

然后将html中的ng-repeats更改为:

<td ng-repeat="history in data.nonEmptyCells" class="my-table-cell">

<td ng-repeat="emptyCell in data.emptyCells" class="empty"></td>

更新了plunkr:http://plnkr.co/edit/92S2rNNhBEyXZVsCI2M8?p=preview

答案 1 :(得分:1)

我相信你可以将ng-repeat的数量减少到只有 2

你只需要改变一下你的方法。不要在每个splice上执行ng-repeat,而是使用具有预定义长度的索引列表/数组。然后,迭代该索引列表,并针对每个索引检查data.Histories数组的相同位置是否存在项。如果有,那么它是'my-table-cell',否则它是'empty'单元格(ng-class可以帮助您定义)。

然后对字段使用相同的逻辑,而不是每个字段有1 ng-repeat,尝试定义字段列表/数组,然后仅使用1 ng-repeat迭代该列表。

最终结果应该是这样的:

<table ng-repeat="data in myData" class="my-table">
  <caption>
    {{ data.Name }}
  </caption>
  <tbody>
    <tr ng-repeat="field in fields">
      <th>{{field}}</th>
      <td ng-repeat="idx in indexes" ng-class="{ 'my-table-cell': data.Histories[idx][field], 'empty': !data.Histories[idx][field]}">
        {{data.Histories[idx][field]}}
      </td>
    </tr>
  </tbody>
</table>

MainCtrl上添加以下行:

// the list of indexes could be populated dynamically...
$scope.indexes = [0,1,2,3,4,5,6,7,8,9,10,11];
$scope.fields = ['Rate', 'Effort', 'Advance', 'Previous', 'Current', 'Code'];

<强> Demo

相关问题