在AngularJS中使用ng-repeat过滤结果6到10的100


77

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

是否有内置的过滤器?

Answers:


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);
      }
    }
  };
}

2
下面的@bluescreen答案(以20票赞成)是正确的答案。请选择一个。
RavenHursT 2014年

2
一直给我关于arr未定义的错误,所以我做了这个arr = arr || []; 返回arr.slice(开始,结束);
James Harrington

我无法用ControllerAs符号表示:jsfiddle.net/r9kvaydh/3
Simon H

1
@SimonHitem in main.items
Michelle Tilley

2
limitTo过滤器现在提供了对定义限制从何处开始的支持 {{ limitTo_expression | limitTo : limit : begin}}
Jiby Jose

133

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

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


该解决方案回答了发球台所提出的问题。但是请注意,这仅适用于第二组结果。它不适用于第一,第三,第四组或其他任何组。(第一个limitTo用源的前10个项目创建一个数组,第二个limitTo然后只能在这些结果内使用。)
Tyler

11
最后一页可能会出错。假设有7个项目,第一页显示项目1-5,第二页显示项目6和7,但此处显示项目3-7。
哈里·奥斯特芬

4
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 我认为这个答案不正确。
connorbode 2014年

@connorbode为什么不呢?你能举个例子吗?
AturSams,2014年

37

我开始使用客户过滤器,但是发现您可以sliceng-repeat表达式内部调用:

<div ng-repeat="item in items.slice(6, 10)">{{item}}</div>

2
最简单的答案。谢谢!我以为第二个参数是长度,但显然是停止位置。
AskYous 2015年

2
它应该位于顶部
Sudhakar

如果您使用的是Angular 1.2.X或更早版本,这是最佳答案
TWR

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>

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

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


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>

负号将占用与last.length相同的项目,然后括号内的负5将跳过前5个项目


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++;

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过滤器的精神”完成测试,可以根据需要具有一些“额外”逻辑,等等。


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]


0

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

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
  }

});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.