Ograniczenie liczby wyświetlanych wyników podczas korzystania z ngRepeat


148

Uważam, że tutoriale AngularJS są trudne do zrozumienia; ten prowadzi mnie przez proces tworzenia aplikacji wyświetlającej telefony. Jestem na etapie 5 i pomyślałem, że w ramach eksperymentu spróbuję pozwolić użytkownikom określić, ilu chcieliby, aby ich wyświetlono. Widok wygląda następująco:

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

Dodałem tę linię, w której użytkownicy mogą wpisać, ile wyników chcą pokazać:

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

Oto mój kontroler:

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

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

Ważną linią jest:

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

Potrafię na stałe zakodować liczbę, aby określić, ile telefonów powinno być wyświetlanych. Jeśli wstawię 5, pokaże się 5. Chcę tylko odczytać liczbę w tym wejściu z widoku i umieścić ją w data.splicewierszu. Próbowałem z cytatami i bez nich, ale żadne z nich nie działa. Jak mam to zrobic?

Odpowiedzi:


345

Nieco bardziej „kątowym sposobem” byłoby użycie prostego limitTofiltru, który natywnie zapewnia 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
Warto zwrócić uwagę - i zaoszczędzić komuś kilka minut - że jeśli używasz „track by” MUSI być ostatni po filtrach.
stephan.com,

3
Czy istnieje sposób, aby uzyskać liczbę dostępnych pozycji, używając filtrów i limitTo? Chciałbym użyć limitToprzycisku „wczytaj więcej”, aby zwiększyć limit. Powinien być wyświetlany tylko wtedy, gdy dostępnych jest więcej rekordów.
Tim Büthe

Co to jest filter:query?
bigpony

@defmx na pytanie OP, querypochodzi zSearch: <input ng-model="query">
jusopi

45

Trochę za późno na imprezę, ale to zadziałało. Mam nadzieję, że ktoś inny uzna to za przydatne.

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

2
Podejrzewam, że byłoby to mniej wydajne niż użycie limitToFilter, jeśli jest to duża tablica, ponieważ każdy element prawdopodobnie musi zostać oceniony
rom99

3
Miałem scenariusz, w którym chciałem pokazać 6 elementów z dużo większej liczby kopii. Użycie ng-if="$index < 6"pozwoliło mi pokazać tylko pierwsze 6, zachowując możliwość przeszukiwania całej tablicy (mam filtr połączony z polem wyszukiwania).
Jeroen Vannevel

To nie jest limit, to ukrywanie całego wyniku, jeśli
policzysz

@ Jek-fdrv - Nie, ng-ifw tym przypadku nie wyrenderuje elementu DOM repeatera, którego wartość $indexjest większa niż 3. jeśli $indexw repeaterze jest 0, 1, or 2, warunek jest truei tworzone są węzły DOM. ng-ifróżni się od ng-hidetego, że elementy nie są dodawane do DOM.
couzzi

2

początkowo przechowywać wszystkie dane

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 przypadkowo umieścił zegarek poza kontrolerem, w którym powinien się znajdować.


2

tutaj jest inny sposób na ograniczenie filtra do html, na przykład chcę wyświetlić 3 listy na raz niż użyję limitTo: 3

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

1

Działa to lepiej w moim przypadku, jeśli masz obiekt lub tablicę wielowymiarową. Pokaże tylko pierwsze elementy, inne będą po prostu ignorowane w pętli.

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

Zmień 5 na to, co chcesz.


0

Użyj filtra limitTo, aby wyświetlić ograniczoną liczbę wyników w ng-repeat.

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

-3

Innym (i myślę, że lepszym) sposobem osiągnięcia tego jest faktyczne przechwycenie danych. LimitTo jest w porządku, ale co, jeśli ograniczasz do 10, gdy twoja tablica faktycznie zawiera tysiące?

Dzwoniąc do mojego serwisu, po prostu zrobiłem to:

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

Ogranicza to to, co jest wysyłane do widoku, więc powinno być znacznie lepsze dla wydajności niż robienie tego na froncie.


Implementacja limitTo i tak używa array.slice (), każda różnica w rozmiarze tablicy powinna mieć taką samą różnicę w wydajności, jak zrobienie tego samodzielnie. github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99

ale limitTo w rzeczywistości nie ogranicza danych wysyłanych do widoku, podczas gdy robi to w ten sposób. Przetestowałem to za pomocą console.log ().
Matt Saunders,

1
Tak, to, co robisz, to wystawianie nowej tablicy na widok (tak naprawdę nie myślałbym o tym jako o „wysyłaniu” czegokolwiek). Jeśli interesowało Cię tylko pierwszych 10 elementów danych, a do danych nie ma odniesień nigdzie indziej, zrobienie tego w ten sposób może zmniejszyć zużycie pamięci (zakładając, że dane mogą być zbierane jako śmieci). Ale jeśli nadal masz odniesienie do dataaround, nie jest to bardziej wydajne niż użycie limitTo.
rom99
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.