Begrenzung der Anzahl der angezeigten Ergebnisse bei Verwendung von ngRepeat

148

Ich finde die AngularJS-Tutorials schwer zu verstehen. Dieser führt mich durch die Erstellung einer App, in der Telefone angezeigt werden. Ich bin in Schritt 5 und dachte, ich würde als Experiment versuchen, Benutzern zu ermöglichen, anzugeben, wie viele sie angezeigt werden möchten. Die Ansicht sieht folgendermaßen aus:

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

Ich habe diese Zeile hinzugefügt, in der Benutzer eingeben können, wie viele Ergebnisse angezeigt werden sollen:

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

Hier ist mein 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;
}

Die wichtige Zeile lautet:

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

Ich kann eine Zahl fest codieren, um darzustellen, wie viele Telefone angezeigt werden sollen. Wenn ich einsetze 5, werden 5 angezeigt. Ich möchte nur die Nummer in dieser Eingabe aus der Ansicht lesen und in die data.spliceZeile einfügen. Ich habe es mit und ohne Anführungszeichen versucht und keine Arbeit. Wie mache ich das?

Captain Stack
quelle

Antworten:

345

Etwas "winkeliger" wäre die Verwendung des einfachen limitToFilters, wie er von Angular nativ bereitgestellt wird:

<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

Stewie
quelle
54
Es lohnt sich darauf hinzuweisen - und jemand anderem ein paar Minuten zu sparen -, dass wenn Sie "Track by" verwenden, es nach den Filtern zuletzt sein muss.
stephan.com
3
Gibt es eine Möglichkeit, die Anzahl der verfügbaren Elemente bei Verwendung von filter und limitTo abzurufen? Ich würde gerne limitToeinen "Mehr laden" -Button verwenden, um das Limit zu erhöhen. Dies sollte nur angezeigt werden, wenn mehr Datensätze verfügbar sind.
Tim Büthe
Was ist filter:query?
Bigpony
@defmx gemäß der Frage des OP, querykommt vonSearch: <input ng-model="query">
jusopi
45

Ein bisschen spät zur Party, aber das hat bei mir funktioniert. Hoffentlich findet es jemand anderes nützlich.

<div ng-repeat="video in videos" ng-if="$index < 3">
    ...
</div>
Couzzi
quelle
2
Ich vermute, dass dies weniger effizient wäre als die Verwendung von limitToFilter, wenn es sich um ein großes Array handelt, da vermutlich jedes Element ausgewertet werden muss
rom99
3
Ich hatte ein Szenario, in dem ich 6 Elemente aus einem Hintergrund-Array von viel mehr zeigen wollte. Mit ng-if="$index < 6"konnte ich nur die ersten 6 anzeigen, während das gesamte Array durchsuchbar blieb (ich habe einen Filter mit einem Suchfeld kombiniert).
Jeroen Vannevel
Es ist keine Begrenzung, es ist das gesamte Ergebnis zu verbergen, wenn mehr als 3 gezählt wird.
fdrv
@ Jek-fdrv - Nein, ng-ifin diesem Fall wird das DOM-Element des Repeaters, dessen $indexgrößer als ist , nicht gerendert 3. Wenn sich $indexim Repeater befindet 0, 1, or 2, ist die Bedingung trueund die DOM-Knoten werden erstellt. ng-ifunterscheidet sich von ng-hidedem Sinne, dass Elemente nicht zum DOM hinzugefügt werden.
Couzzi
2

Speichern Sie zunächst alle Ihre Daten

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 hatte die Uhr versehentlich außerhalb des Controllers platziert, in dem sie sich befinden sollte.

Shaunhusain
quelle
2

Hier ist eine andere Möglichkeit, Ihren Filter auf HTML zu beschränken. Ich möchte beispielsweise 3 Listen gleichzeitig anzeigen, als ich limitTo: 3 verwenden werde

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

Dies funktioniert in meinem Fall besser, wenn Sie ein Objekt oder ein mehrdimensionales Array haben. Es werden nur die ersten Elemente angezeigt, andere werden in der Schleife einfach ignoriert.

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

Ändern Sie 5 auf was Sie wollen.

fdrv
quelle
0

Verwenden Sie den Filter limitTo, um eine begrenzte Anzahl von Ergebnissen in ng-repeat anzuzeigen.

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

Eine andere (und meiner Meinung nach bessere) Möglichkeit, dies zu erreichen, besteht darin, die Daten tatsächlich abzufangen. limitTo ist in Ordnung, aber was ist, wenn Sie auf 10 beschränken, wenn Ihr Array tatsächlich Tausende enthält?

Als ich meinen Dienst anrief, tat ich einfach Folgendes:

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

Dies schränkt ein, was an die Ansicht gesendet wird, und sollte daher für die Leistung viel besser sein als dies im Front-End zu tun.

Matt Saunders
quelle
Implementierung von limitTo verwendet ohnehin array.slice (). Jeder Unterschied in der Größe des Arrays sollte den gleichen Unterschied in der Leistung haben wie selbst. github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99
Mit limitTo werden die an die Ansicht gesendeten Daten jedoch nicht eingeschränkt, während dies auf diese Weise der Fall ist. Ich habe dies mit console.log () getestet.
Matt Saunders
1
Ja, Sie setzen der Ansicht ein neues Array zur Verfügung (ich würde es nicht wirklich als "Senden" von irgendwoher betrachten). Wenn Sie nur an den ersten 10 Elementen in Daten interessiert waren und auf keine Daten verwiesen wird, kann dies auf diese Weise den Speicherbedarf verringern (vorausgesetzt, Daten können durch Müll gesammelt werden). Wenn Sie jedoch immer noch einen Verweis auf dataaround behalten , ist dies nicht effizienter als die Verwendung von limitTo.
Rom99