Limitation du nombre de résultats affichés lors de l'utilisation de ngRepeat

148

Je trouve les didacticiels AngularJS difficiles à comprendre; celui-ci me guide à travers la création d'une application qui affiche les téléphones. Je suis à l' étape 5 et j'ai pensé à titre expérimental que j'essaierais de permettre aux utilisateurs de spécifier combien ils aimeraient voir apparaître. La vue ressemble à ceci:

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

J'ai ajouté cette ligne où les utilisateurs peuvent entrer le nombre de résultats qu'ils souhaitent afficher:

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

Voici mon contrôleur:

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

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

La ligne importante est:

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

Je peux coder en dur un nombre pour représenter le nombre de téléphones à afficher. Si je mets 5, 5 seront affichés. Tout ce que je veux faire, c'est lire le numéro de cette entrée dans la vue et le mettre dans la data.spliceligne. J'ai essayé avec et sans guillemets, et aucun travail. Comment puis-je faire cela?

Capitaine Stack
la source

Réponses:

345

Un peu plus "Angular way" serait d'utiliser le limitTofiltre simple , comme fourni nativement par 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

Stewie
la source
54
Cela vaut la peine de souligner - et de gagner quelques minutes à quelqu'un d'autre - que si vous utilisez "track by", il DOIT être le dernier après les filtres.
stephan.com
3
Existe-t-il un moyen d'obtenir le nombre d'éléments disponibles lors de l'utilisation de filter et limitTo? Je voudrais utiliser limitTomais fournir un bouton "charger plus" pour augmenter la limite. Cela ne devrait être affiché que si plus d'enregistrements sont disponibles.
Tim Büthe
C'est quoi filter:query?
bigpony
@defmx par la question du PO, queryvient deSearch: <input ng-model="query">
jusopi
45

Un peu tard à la fête, mais cela a fonctionné pour moi. Espérons que quelqu'un d'autre le trouve utile.

<div ng-repeat="video in videos" ng-if="$index < 3">
    ...
</div>
couzzi
la source
2
Je soupçonne que ce serait moins efficace que d'utiliser limitToFilter s'il s'agit d'un grand tableau, car chaque élément doit probablement être évalué
rom99
3
J'ai eu un scénario où je voulais montrer 6 éléments à partir d'un tableau de support bien plus. L'utilisation ng-if="$index < 6"m'a permis d'afficher uniquement les 6 premiers tout en gardant le tableau entier interrogeable (j'ai un filtre combiné avec un champ de recherche).
Jeroen Vannevel le
Ce n'est pas une limite, c'est cacher tout le résultat si compter plus de 3.
fdrv
@ Jek-fdrv - Non, ng-ifdans ce cas, ne rendra pas l'élément DOM du répéteur dont la valeur $indexest supérieure à 3. si $indexdans le répéteur est 0, 1, or 2, la condition est trueet les nœuds DOM sont créés. ng-ifdiffère de ng-hideen ce sens que les éléments ne sont pas ajoutés au DOM.
couzzi
2

stocker toutes vos données dans un premier temps

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 avait accidentellement mis la montre à l'extérieur du contrôleur, elle aurait dû être à l'intérieur.

shaunhusain
la source
2

voici une autre façon de limiter votre filtre sur html, par exemple je veux afficher 3 liste à la fois que j'utiliserai limitTo: 3

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

Cela fonctionne mieux dans mon cas si vous avez un objet ou un tableau multidimensionnel. Il ne montrera que les premiers éléments, les autres seront simplement ignorés en boucle.

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

Changez 5 sur ce que vous voulez.

fdrv
la source
0

Utilisez limitTo filter pour afficher un nombre limité de résultats dans ng-repeat.

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

Un autre moyen (et je pense qu'il est préférable) d'y parvenir est d'intercepter les données. limitTo est correct, mais que se passe-t-il si vous limitez à 10 alors que votre tableau contient en fait des milliers?

En appelant mon service, j'ai simplement fait ceci:

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

Cela limite ce qui est envoyé à la vue, donc cela devrait être bien meilleur pour les performances que de le faire sur le front-end.

Matt Saunders
la source
Implémentation de limit Pour utiliser de toute façon array.slice (), toute différence de taille de tableau doit avoir la même différence de performances que de le faire vous-même. github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99
mais limitTo ne limite pas réellement les données envoyées à la vue, alors que cela le fait de cette manière. J'ai testé cela en utilisant console.log ().
Matt Saunders
1
Oui, ce que vous faites est d'exposer un nouveau tableau à la vue (je ne penserais pas vraiment à cela comme «envoyer» quoi que ce soit). Si vous n'étiez intéressé que par les 10 premiers éléments des données et que les données ne sont référencées nulle part ailleurs, cela pourrait réduire l'empreinte mémoire (en supposant que les données peuvent être récupérées). Mais si vous gardez toujours une référence à dataaround, ce n'est pas plus efficace que d'utiliser limitTo.
rom99