Обмеження кількості відображуваних результатів при використанні ngRepeat


148

Мені здається, що підручники 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рядку. Я намагався з цитатами і без них, і жодної роботи. Як це зробити?

Відповіді:


345

Трохи більш «кутовим способом» було б використовувати прямий 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


54
Варто зазначити - і заощадити когось іншого на кілька хвилин - що якщо ви використовуєте "трек", ОБОВ'ЯЗКОВО буде останнє після фільтрів.
stephan.com

3
Чи є спосіб отримати кількість доступних елементів при використанні фільтра та limitTo? Я хотів би скористатися, limitToале надати кнопку "завантажити більше" для збільшення ліміту. Це має відображатися лише за наявності більшої кількості записів.
Тім Б’юте

Що таке filter:query?
bigpony

@defmx на запитання ОП, queryпоходить відSearch: <input ng-model="query">
jusopi

45

Трохи запізнився на вечірку, але це працювало для мене. Сподіваємось, хтось інший вважає це корисним.

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

2
Я підозрюю, що це буде менш ефективно, ніж використання limitToFilter, якщо це великий масив, тому що, мабуть, слід оцінювати кожен елемент
rom99,

3
У мене був сценарій, коли я хотів показати 6 елементів із резервного масиву набагато більше. Використання ng-if="$index < 6"дозволило мені показати лише перші 6, зберігаючи весь масив для пошуку (у мене є фільтр, поєднаний із полем пошуку).
Jeroen Vannevel

Це не межа, це приховати весь результат, якщо порахувати більше 3
fdrv

@ Jek-fdrv - Ні, ng-ifв цьому випадку не буде надано елемент DOM ретранслятора, чий $indexбільший ніж 3. якщо $indexв ретрансляторі є 0, 1, or 2, умова є trueі створюються вузли DOM. ng-ifвідрізняється ng-hideтим, що елементи не додаються до DOM.
куззі

2

зберігати всі свої дані спочатку

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 випадково поставив годинник поза контролером, він повинен був знаходитися всередині.


2

ось анатотер спосіб обмежити ваш фільтр на html, наприклад, я хочу вчасно відобразити 3 списку, ніж я буду використовувати limitTo: 3

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

1

Це краще працює в моєму випадку, якщо у вас є об’єкт або багатовимірний масив. Він відображатиме лише перші елементи, інші будуть просто проігноровані в циклі.

.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 на те, що ви хочете.


0

Використовуйте limitTo фільтр, щоб відобразити обмежену кількість результатів у ng-повторах.

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

-3

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

Зателефонувавши на службу, я просто зробив це:

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

Це обмежує те, що надсилається для перегляду, тому повинно бути набагато кращим для продуктивності, ніж робити це на передовій.


Реалізація limitTo використовує array.slice () у будь-якому випадку, будь-яка різниця у розмірі масиву повинна мати таку ж різницю у продуктивності, як і самостійно. github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99

але limitTo фактично не обмежує дані, що надсилаються до перегляду, тоді як це робиться таким чином. Я перевірив це за допомогою console.log ().
Метт Сондерс

1
Так, те, що ви робите, це піддавати новий масив перегляду (я б не дуже вважав це "надсиланням" будь-чого). Якщо вас цікавили лише перші 10 елементів даних, а дані ніде не посилаються, це може призвести до зменшення сліду пам’яті (якщо припустити, що дані можуть бути зібрані сміттям). Але якщо ви все ще зберігаєте посилання на dataнавколо, це не є більш ефективним, ніж використання limitTo.
rom99
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.