77

我在文档中看到了limitTo过滤器,它允许我限制前 5 个或最后 5 个结果,但我想设置限制的开始位置,以便显示第二组 5 个结果。

有内置过滤器吗?

4

10 回答 10

147

从 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.0 实现limitTo

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);
      }
    }
  };
}
于 2013-02-10T09:09:33.107 回答
133

AngularJS 提供了开箱即用的功能。如果您仔细阅读 limitTo 文档,它允许您为限制指定负值。这意味着最后有 N 个元素,因此如果要在偏移 5 后处理 5 个结果,则需要执行以下操作:

<div ng-repeat="item in items | limitTo: 10 | limitTo: -5">{{item}}</div>

于 2013-07-19T22:04:10.067 回答
37

我开始使用客户过滤器,但后来发现您可以在表达式slice内部调用:ng-repeat

<div ng-repeat="item in items.slice(6, 10)">{{item}}</div>
于 2014-08-27T20:02:43.093 回答
4

正如蓝屏所说,它可以只使用limitTo过滤器来完成,尽管处理Harry Oosterveen 注意到的最后一页问题需要一些额外的工作。

即使用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>
于 2014-07-11T15:57:41.667 回答
3

这是一个关于如何使用偏移量和限制过滤列表的功能示例:

<!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 教程的第二步

请注意,如果要涵盖限制为 uknnown 的一般情况,则必须将偏移量过滤器作为第一个过滤器。

于 2014-01-07T21:34:46.980 回答
2

来自蓝屏答案:

<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 个项目

于 2014-10-09T10:03:53.617 回答
1

有一种更简洁的方法可以做到这一点,而不必调用过滤器,并且表现得更像分页器:

$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++;
于 2014-08-15T14:28:41.057 回答
1

您还可以像这样创建自己的可重用过滤器 startFrom:

myApp.filter('startFrom', function () {
    return function (input, start) {
        start = +start;
        return input.slice(start);
    }
});

然后像这样在你的 ng-repeat 中使用它:

ng-repeat="item in items | startFrom: 5 | limitTo:5

这样它是“本着 AngularJs 过滤器的精神”完成的,可测试的,如果需要可以有一些“额外的”逻辑,等等。

于 2015-09-17T23:03:47.687 回答
0

@bluescreen 的 ans 和 @Brandon 的 ans 不等价。

例如:

var pageSize = 3;  
var page = 2;
var items = [1, 2, 3, 4];  

--

item in items | limitTo: page*pageSize | limitTo: -1*pageSize  

产生 [2, 3, 4]

item in items | slice: (page-1)*pageSize : page*pageSize  

生产 [4]

于 2015-02-09T21:47:21.183 回答
0

对于基于 Ionic 的项目,请找到以下解决方案:

主页.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>

控制器.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
  }

});
于 2016-07-08T12:11:25.753 回答