Ng-repeat с несколькими фильтрами на большом наборе данных
Я все еще новичок в AngularJS, поэтому я просто пытаюсь сделать простое приложение CRUD. В настоящее время я вытаскиваю данные (в файле JSON) с $http
в div
, обрабатываемом контроллером MyCtrl1
.
function MyCtrl1($scope, $http) {
$http.get('data/accounts.json').success(function(data) {
$scope.accounts = data;
...
});
}
Внутри этого div
есть table
со следующим tbody
:
<tbody>
<tr ng-repeat="account in accounts | orderBy:sort.field:sort.desc | startFrom:currentPage * pageSize | limitTo:pageSize">
<td contentEditable="true" ng-repeat="(label, value) in account" ng-show="fields[label].visible">{{value}}</td>
</tr>
</tbody>
Фильтр orderBy
сортируется в соответствии с выбранным полем; startFrom
срезает массив, чтобы начать с определенной точки; limitTo
фильтрует в соответствии с заданным размером страницы. Без фильтров разбиения на страницы производительность была довольно ужасной, но мне было интересно, есть ли альтернативный способ сделать это?
У меня есть Batarang для Chrome, а на вкладке Performance он показал ngRepeatWatch
больше времени, и я считаю, что это связано со всей фильтрацией, которую я делаю.
Ответы
Ответ 1
{{выражение | фильтр1 | filter2}}
Просто используйте
<tr ng-repeat="account in accounts | filter1 | filter2 | filter3" >
<td contentEditable="true" ng-repeat="(label, value) in account" ng-show="fields[label].visible">{{value}}</td>
</tr>
Angular 2 использует pipes, но он выглядит как фильтры:
<div>The chained hero birthday is
<p>{{ birthday | date:'fullDate' | uppercase}}</p>
<div>
Ответ 2
Я знаю, что этот вопрос старый, но для любого в будущем. Фильтрация в строке дорогостоящая (вычислительная), потому что она работает непосредственно на DOM, если вы имеете дело с большими объемами данных, 1000+ строк, гораздо лучше отфильтровать вашу коллекцию в контроллере, а затем повторить на этом.
Ответ 3
Я бы обрабатывал разбиение на страницы в контроллере или на стороне сервера. Я предполагаю, что ng-repeat просматривает весь ваш список, а не только то, что ему нужно наблюдать, что будет очень медленным.
Ответ 4
Это не фильтр, но вы можете использовать директиву ng-hide, оценивая индекс $для массива следующим образом:
<div class="col-sm-12 col-lg-12" ng-repeat="message in messages | orderBy: '-id' as filtered_result track by message.id ">
<div class="card-box widget-user" ng-hide="{{$index >= 4}}">
<div>
<img ng-src="{{message.imageUrl}}" class="img-responsive" alt="{{message.imageUrl}}">
<div class="wid-u-info">
<h3 class="m-t-0 m-b-5">{{message.title }}</h3>
<p class="text-muted m-b-5 font-13" ng-bind-html="message.content | ellipsis:147 | trusted"></p>
<!-- <p class="text-muted m-b-5 font-13">{{message.content | limitTo:130}}</p> -->
<small class="label" ng-class="{'label-success':message.type=='Message','label-warning':message.type=='Announcement'}"><b>{{message.type}}</b></small>
</div>
</div>
</div>
</div>
Ответ 5
CRUD следует обрабатывать в factory или службе, а не в контроллере. Я понимаю, что контроллер несет ответственность только за связь между представлениями и услугами.
Изменить 1: выдержка из руководства по стилю Джона Папа (Angular -1) - Отложить логику в контроллере, делегируя сервисам и фабрикам.
Почему?: Логика может быть повторно использована несколькими контроллерами при размещении внутри службы и открыта с помощью функции.
Почему?: Логика в сервисе проще изолировать в unit test, в то время как логику вызова в контроллере можно легко высмеять.
Почему?: Удаляет зависимости и скрывает детали реализации от контроллера.
Почему?: Сохраняет контроллер тонким, аккуратным и сфокусированным.
https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y035