Ограничение количества отображаемых результатов при использовании ngRepeat

Я считаю учебники по AngularJS трудными для понимания; этот рассказывает мне о создании приложения, которое отображает телефоны. Я на шаге 5, и я подумал, что в качестве эксперимента я попытался позволить пользователям указать, сколько они хотели бы показать. Вид выглядит следующим образом:

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

Я добавил эту строку, где пользователи могут указать, сколько результатов они хотят показать:

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

Вот мой контроллер:

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

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

Важная строка:

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

Я могу жестко ввести число, чтобы показать, сколько телефонов должно быть показано. Если я вставлю 5, будет показано 5. Все, что я хочу сделать, это прочитать число в этом входе из представления и поместить его в строку data.splice. Я пробовал с и без кавычек, и ни одна не работает. Как мне это сделать?

Ответ 1

Чуть больше "Angular путь" должен был бы использовать простой фильтр limitTo, как это предусмотрено 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

Немного поздно на вечеринку, но это сработало для меня. Надеюсь, кто-то найдет это полезным.

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

Ответ 3

сначала сохраните все ваши данные.

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 случайно поставил часы вне контроллера, они должны были быть внутри.

Ответ 4

Вот еще один способ ограничить ваш фильтр на HTML, например, я хочу отобразить 3 списка за раз, чем я буду использовать limitTo: 3

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

Ответ 5

Это работает лучше в моем случае, если у вас есть объект или многомерный массив. Он отображает только первые элементы, другие будут просто проигнорированы в цикле.

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

Измените 5 на то, что вы хотите.

Ответ 6

Используйте фильтр limitTo для отображения ограниченного числа результатов в ng-repeat.

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

Ответ 7

Другой (и я думаю, лучше) способ достичь этого - фактически перехватить данные. limitTo в порядке, но что, если вы ограничиваете 10, когда ваш массив действительно содержит тысячи?

При вызове моего сервиса я просто сделал это:

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

Это ограничивает то, что отправлено в представление, поэтому должно быть намного лучше для производительности, чем для этого в интерфейсе.