Я бачу limitToфільтр у документації, який дозволяє мені обмежити перші 5 або останні 5 результатів, але я хочу встановити, де починається мій ліміт, щоб я міг показати другий набір із 5 результатів.
Чи є для цього вбудований фільтр?
Відповіді:
Починаючи з Angular 1.4.0, limitToфільтр бере необов'язковий beginаргумент:
<div ng-repeat="item in items | limitTo:5:5">{{item}}</div>
У старих версіях написання власного фільтра досить просто. Ось наївна реалізація, заснована на Array#slice(зверніть увагу, ви передаєте перший і останній індекс, а не підрахунок):
app.filter('slice', function() {
return function(arr, start, end) {
return (arr || []).slice(start, end);
};
});
<div ng-repeat="item in items | slice:6:10">{{item}}</div>
Робочий jsFiddle: http://jsfiddle.net/BinaryMuse/vQUsS/
Крім того, ви можете просто викрасти всю реалізацію Angular 1.4.0limitTo :
function limitToFilter() {
return function(input, limit, begin) {
if (Math.abs(Number(limit)) === Infinity) {
limit = Number(limit);
} else {
limit = toInt(limit);
}
if (isNaN(limit)) return input;
if (isNumber(input)) input = input.toString();
if (!isArray(input) && !isString(input)) return input;
begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
begin = (begin < 0 && begin >= -input.length) ? input.length + begin : begin;
if (limit >= 0) {
return input.slice(begin, begin + limit);
} else {
if (begin === 0) {
return input.slice(limit, input.length);
} else {
return input.slice(Math.max(0, begin + limit), begin);
}
}
};
}
ControllerAsпозначенням: jsfiddle.net/r9kvaydh/3
item in main.items
{{ limitTo_expression | limitTo : limit : begin}}
AngularJS надає цю функціональність вже нестандартно. Якщо ви уважно прочитаєте ліміт До документації, це дозволяє вказати від’ємне значення для ліміту. Це означає N елементів в кінці, тому, якщо ви хочете обробити 5 результатів після зсуву 5, вам потрібно зробити наступне:
<div ng-repeat="item in items | limitTo: 10 | limitTo: -5">{{item}}</div>
The length of the returned array or string. If the limit number is positive, limit number of items from the beginning of the source array/string are copied. If the number is negative, limit number of items from the end of the source array/string are copied. The limit will be trimmed if it exceeds array.length Я вважаю, що ця відповідь не правильна.
Я почав пограти з фільтрами клієнтів, але потім з'ясував, що ви можете просто зателефонувати sliceвсередині ng-repeatвиразу:
<div ng-repeat="item in items.slice(6, 10)">{{item}}</div>
Як сказав bluescreen, це можна зробити, використовуючи лише limitTo фільтр, хоча вирішення проблеми останньої сторінки, яку помітив Гаррі Остервен, потребує додаткової роботи.
Тобто за допомогою ui-bootstrap pagination властивостей директиви :
ng-model = page // current page
items-per-page = rpp // records per page
total-items = count // total number of records
Вираз повинен бути:
<div ng-repeat="item in items | limitTo: rpp * page | limitTo: rpp * page < count ? -rpp : rpp - (rpp * page - count)">{{item}}</div>
Ось функціональний приклад того, як фільтрувати список зі зміщенням та обмеженням:
<!doctype html>
<html lang="en" ng-app="phonecatApp">
<head>
<script src="lib/angular/angular.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
Offset: <input type="text" ng-model="offset" value="0" /><br />
Limit: <input type="text" ng-model="limit" value="10" /><br />
<p>offset limitTo: {{offset - phones.length}}</p>
<p>Partial list:</p>
<ul>
<li ng-repeat="phone in phones | limitTo: offset - phones.length | limitTo: limit">
{{$index}} - {{phone.name}} - {{phone.snippet}}
</li>
</ul>
<hr>
<p>Whole list:</p>
<ul>
<li ng-repeat="phone in phones">
{{$index}} - {{phone.name}} - {{phone.snippet}}
</li>
</ul>
</body>
</html>
Приклад заснований на другому кроці підручника з AngularJS .
Зверніть увагу, що фільтр для зміщення повинен бути встановлений як перший фільтр, якщо ви хочете охопити загальний випадок, коли межа невідома.
з відповіді на блюз екрані:
<div ng-repeat="item in items | limitTo: 10 | limitTo: -5">{{item}}</div>
Ви також можете знайти сценарій, коли вам потрібно буде взяти N-й предмет до останнього предмета , це інший спосіб використання limitTo:
<div ng-repeat="item in items | limitTo:-(items.length-5)>{{item}}</div>
негативний знак займе стільки, скільки items.length від останнього, тоді мінус 5 всередині дужки пропустить перші 5 елементів
Існує більш акуратний спосіб зробити це без необхідності викликати фільтр і буде поводитися більше як пагінатор:
$scope.page = 0;
$scope.items = [ "a", "b", "c", "d", "e", "f", "g" ];
$scope.itemsLimit = 5;
$scope.itemsPaginated = function () {
var currentPageIndex = $scope.page * $scope.itemsLimit;
return $scope.items.slice(
currentPageIndex,
currentPageIndex + $scope.itemsLimit);
};
І просто дотримуйтесь цього на ваш погляд:
<ul>
<li ng-repeat="item in itemsPaginated() | limitTo:itemsLimit">{{item}}</li>
</ul>
Тоді ви можете просто збільшити / зменшити $scope.page:
$scope.page++;
Ви також можете створити свій власний багаторазовий фільтр startFrom приблизно так:
myApp.filter('startFrom', function () {
return function (input, start) {
start = +start;
return input.slice(start);
}
});
а потім використовуйте його у своєму ng-повторенні приблизно так:
ng-repeat="item in items | startFrom: 5 | limitTo:5
Таким чином, це робиться "в дусі фільтрів AngularJs", перевіряється, може мати певну "додаткову" логіку, якщо потрібно, і т.д.
Для іонних проектів знайдіть рішення нижче:
mainpage.html:
<ion-view view-title="My Music">
<ion-content>
<ion-list>
<ion-item ng-repeat="track in tracks | limitTo: limit | limitTo: -10 ">
{{track.title}}
</ion-item>
</ion-list>
<div class="list"></div>
<div align="center">
<button class="button button-small button-positive" ng-disabled="currentPage == 0" ng-click="decrementLimit()">
Back
</button>
<button class="button button-small button-energized">
{{currentPage+1}}/{{numberOfPages()}}
</button>
<button class="button button-small button-positive" ng-disabled="currentPage >= data_length/pageSize - 1" ng-click="incrementLimit()">
Next
</button>
</div>
</ion-content>
</ion-view>
controller.js:
var myApp = angular.module('musicApp.controllers', []);
myApp.controller('AppCtrl', function($scope, $http) {
console.log('AppCtrl called');
// $scope.tracks = MusicService.query();
$http.get('api/to/be/called').then(function(result){
$scope.tracks = result.data['results'];
$scope.data_length = $scope.tracks.length;
console.log(result)
// console.log($sco pe.tracks.length)
});
var currentPage = 0;
$scope.pageSize = 10;
$scope.numberOfPages = function(){
return Math.ceil($scope.tracks.length/$scope.pageSize);
}
var limitStep = 10;
$scope.limit = limitStep;
$scope.currentPage = currentPage;
$scope.incrementLimit = function(){
$scope.limit += limitStep;
$scope.currentPage += 1
};
$scope.decrementLimit = function(){
$scope.limit -= limitStep;
$scope.currentPage -= 1
}
});