ngRepeat - limiting number of displayed results

2019-01-07 04:52发布

问题:

I'm a huge AngularJS n00b and am finding even the tutorials hard to understand. This tutorial is walking me through building an app that displays phones. I'm on step 5 and I thought as an experiment I'd try to allow users to specify how many they'd like to be shown. The view looks like this:

<body ng-controller="PhoneListCtrl">

  <div class="container-fluid">
    <div class="row-fluid">
      <div class="span2">
        <!--Sidebar content-->

        Search: <input ng-model="query">
        How Many: <input ng-model="quantity">
        Sort by:
        <select ng-model="orderProp">
          <option value="name">Alphabetical</option>
          <option value="age">Newest</option>
        </select>

      </div>
      <div class="span10">
        <!--Body content-->

        <ul class="phones">
          <li ng-repeat="phone in phones | filter:query | orderBy:orderProp">
            {{phone.name}}
            <p>{{phone.snippet}}</p>
          </li>
        </ul>

      </div>
    </div>
  </div>
</body>

I've added this line that users can enter how many results they want shown:

How Many: <input ng-model="quantity">

Here's my controller:

function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data.splice(0, 'quantity');
  });

  $scope.orderProp = 'age';
  $scope.quantity = 5;
}

The important line is:

$scope.phones = data.splice(0, 'quantity');

I can hard-code in a number to represent how many phones should be shown. If I put 5 in, 5 will be shown. All I want to do is read the number in that input from the view, and put that in the data.splice line. I've tried with and without quotes, and neither work. How do I do this?

回答1:

Slightly more "Angular way" would be to use the straightforward limitTo filter, as natively provided by Angular:

<ul class="phones">
  <li ng-repeat="phone in phones | filter:query | orderBy:orderProp | limitTo:quantity">
    {{phone.name}}
    <p>{{phone.snippet}}</p>
  </li>
</ul>
app.controller('PhoneListCtrl', function($scope, $http) {
    $http.get('phones.json').then(
      function(phones){
        $scope.phones = phones.data;
      }
    );
    $scope.orderProp = 'age';
    $scope.quantity = 5;
  }
);

PLUNKER



回答2:

A little late to the party, but this worked for me. Hopefully someone else finds it useful.

<div ng-repeat="video in videos" ng-if="$index < 3">
    ...
</div>


回答3:

store all your data initially

function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data.splice(0, 5);
    $scope.allPhones = data;
  });

  $scope.orderProp = 'age';
  $scope.howMany = 5;
  //then here watch the howMany variable on the scope and update the phones array accordingly
  $scope.$watch("howMany", function(newValue, oldValue){
    $scope.phones = $scope.allPhones.splice(0,newValue)
  });
}

EDIT had accidentally put the watch outside the controller it should have been inside.



回答4:

here is anaother way to limit your filter on html, for example I want to display 3 list at time than i will use limitTo:3

  <li ng-repeat="phone in phones | limitTo:3">
    <p>Phone Name: {{phone.name}}</p>
  </li>


回答5:

This works better in my case if you have object or multi-dimensional array. It will shows only first items, other will be just ignored in loop.

.filter('limitItems', function () {
  return function (items) {
    var result = {}, i = 1;
    angular.forEach(items, function(value, key) {
      if (i < 5) {
        result[key] = value;
      }
      i = i + 1;
    });
    return result;
  };
});

Change 5 on what you want.



回答6:

Use limitTo filter to display a limited number of results in ng-repeat.

<ul class="phones">
      <li ng-repeat="phone in phones | limitTo:5">
        {{phone.name}}
        <p>{{phone.snippet}}</p>
      </li>
</ul>


回答7:

Another (and I think better) way to achieve this is to actually intercept the data. limitTo is okay but what if you're limiting to 10 when your array actually contains thousands?

When calling my service I simply did this:

TaskService.getTasks(function(data){
    $scope.tasks = data.slice(0,10);
});

This limits what is sent to the view, so should be much better for performance than doing this on the front-end.