0

У меня есть регистр, который перечисляет людей в алфавитном порядке от A до Z ... Каждый человек, например г-н A, имеет набор соответствующих данных Histories.AngularJS - Уменьшение количества ng-повторов

У меня есть таблица с простым ng-repeat, который отображает данные для 12 ячеек (представляющих 12 месяцев).

Если предоставляется 12 месяцев/ячеек данных, я показываю все данные, если предоставляется только 5 месяцев данных (всего менее 12), я вызываю услугу srvEmptyCells, которая вычисляет оставшиеся ячейки и отображает их в темный цвет.

Проблемы с этим, что я замечаю я повторив нг-повтор:

emptyCell in getEmptyCells 

много много раз, воздействующих на производительность страницы даются у меня есть более 100 пользователей.

Есть ли способ сохранить количество пустых ячеек для каждого конкретного пользователя? И удалить необходимость дополнительных ng-repeats? Будет ли директива улучшаться?

Херес 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; 
     } 
    }; 
}); 

ответ

1

Вы можете изменить $scope.myData, добавив кэшированные версии data.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 для:

<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

+0

Спасибо за вход, к сожалению, я наклоняю измените, какие данные возвращаются. Какое решение кажется интересным, любые примеры? –

+1

проверить сейчас, может быть способ сделать это, вызвав функцию .memoize, но я должен уйти сейчас –

+0

Спасибо, например, может ли цикл for быть помещен в мой контроллер, а не в Factory? Memoization выглядит интересно, но я никогда не использовал его и не знал, с чего начать? Было бы просто в этом случае? –

1

Я считаю, что вы можете уменьшить количество ng-repeat до .

Вам просто нужно немного изменить свой подход. Вместо того, чтобы делать splice на каждом ng-repeat, используйте список/массив индексов с предопределенной длиной. Затем перебираем этот список индексов и для каждого индекса проверяем, есть ли элемент в той же позиции массива .Если есть, то это '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

+0

@bmliete - Wow! Отличный вариант .. Что делать, если на лицевой стороне я хотел отобразить «Предыдущая сумма» вместо «Предыдущая», но не могу изменить свой файл JSON. –

+1

Да, вы можете изменить заказ, как хотите. Чтобы отобразить другую метку, просто используйте «Объекты» вместо «Строки» и сделайте небольшие изменения в HTML. Проверьте это [plunkr] (http://plnkr.co/edit/s32GHTgQ1Il41dbwMtQ0?p=preview). – bmleite

+0

Спасибо! Любая причина, когда ячейка равна нулю, она не омрачается на лицевой стороне? –

Смежные вопросы