Limitación del número de resultados mostrados al usar ngRepeat

6 minutos de lectura

avatar de usuario
capitán pila

encuentro el Tutoriales de AngularJS difícil de entender; este me está guiando a través de la construcción de una aplicación que muestra teléfonos. Estoy en paso 5 y pensé que, como experimento, intentaría permitir que los usuarios especificaran cuántos les gustaría que se mostraran. La vista se ve así:

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

Agregué esta línea donde los usuarios pueden ingresar cuántos resultados quieren que se muestren:

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

Aquí está mi controlador:

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 línea importante es:

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

Puedo codificar un número para representar cuántos teléfonos se deben mostrar. si pongo 5 en, se mostrará 5. Todo lo que quiero hacer es leer el número en esa entrada de la vista y ponerlo en el data.splice línea. He probado con y sin comillas, y tampoco funciona. ¿Cómo hago esto?

avatar de usuario
Stewie

Un poco más de “forma angular” sería usar el sencillo limitTo filtro, proporcionado de forma nativa por 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

  • Vale la pena señalar, y ahorrarle unos minutos a alguien más, que si está utilizando “seguimiento por”, DEBE ser el último después de los filtros.

    – stephan.com

    15 de julio de 2015 a las 3:25

  • ¿Hay alguna manera de obtener la cantidad de elementos disponibles al usar filter y limitTo? me gustaría usar limitTo pero proporcione un botón “cargar más” para aumentar el límite. Esto solo debe mostrarse si hay más registros disponibles.

    – Tim Büthe

    17 de noviembre de 2015 a las 13:54

  • Que es filter:query ?

    – 0x777

    28 de enero de 2016 a las 2:24


  • @defmx según la pregunta del OP, query viene de Search: <input ng-model="query">

    – jusopi

    12 de marzo de 2016 a las 3:28

Un poco tarde para la fiesta, pero esto funcionó para mí. Esperemos que alguien más lo encuentre útil.

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

  • Sospecho que esto sería menos eficiente que usar limitToFilter si se trata de una matriz grande, porque presumiblemente cada elemento debe evaluarse

    – rom99

    5 de agosto de 2015 a las 16:44

  • Tenía un escenario en el que quería mostrar 6 elementos de una matriz de respaldo de mucho más. Usando ng-if="$index < 6" me permitió mostrar solo los primeros 6 mientras mantengo la búsqueda en toda la matriz (tengo un filtro combinado con un campo de búsqueda).

    – Jeroen Vannevel

    04/09/2015 a las 13:56

  • No es límite, es ocultar todo el resultado si cuenta más de 3.

    – fdrv

    1 de abril de 2016 a las 3:39

  • @Jek-fdrv – No, ng-ifen este caso, no representará el elemento DOM del repetidor cuyo $index es mayor que 3. si $index en el repetidor es 0, 1, or 2la condición es true y se crean los nodos DOM. ng-if difiere de ng-hide en el sentido de que los elementos son no añadido al DOM.

    – couzzi

    01/04/2016 a las 18:33


aquí hay otra forma de limitar su filtro en html, por ejemplo, quiero mostrar 3 listas a la vez de las que usaré limite a: 3

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

almacenar todos sus datos inicialmente

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

EDITAR accidentalmente había puesto el reloj fuera del controlador en el que debería haber estado.

avatar de usuario
fdrv

Esto funciona mejor en mi caso si tiene un objeto o una matriz multidimensional. Mostrará solo los primeros elementos, otros simplemente se ignorarán en el bucle.

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

Cambia 5 por lo que quieras.

avatar de usuario
Rajkiran Shetty

Use el filtro limitTo para mostrar un número limitado de resultados en ng-repeat.

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

avatar de usuario
matt saunders

Otra forma (y creo que mejor) de lograr esto es interceptar los datos. limitTo está bien, pero ¿qué sucede si está limitando a 10 cuando su matriz en realidad contiene miles?

Al llamar a mi servicio, simplemente hice esto:

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

Esto limita lo que se envía a la vista, por lo que debería ser mucho mejor para el rendimiento que hacer esto en el front-end.

  • La implementación de limitTo usa array.slice() de todos modos, cualquier diferencia en el tamaño de la matriz debería tener la misma diferencia en el rendimiento que si lo hiciera usted mismo. github.com/angular/angular.js/blob/master/src/ng/filter/…

    – rom99

    5 de agosto de 2015 a las 16:41

  • pero limitTo en realidad no limita los datos enviados a la vista, mientras que hacerlo de esta manera sí lo hace. Probé esto usando console.log().

    – Matt Saunders

    5 de agosto de 2015 a las 17:07

  • Sí, lo que está haciendo es exponer una nueva matriz a la vista (realmente no pensaría en ello como ‘enviar’ nada a ninguna parte). Si solo estaba interesado en los primeros 10 elementos de los datos y no se hace referencia a los datos en ningún otro lugar, hacerlo de esta manera podría reducir el consumo de memoria (suponiendo que los datos se puedan recolectar basura). Pero si todavía mantiene una referencia a data alrededor, esto no es más eficiente que usar limitTo.

    – rom99

    6 ago. 2015 a las 9:00

¿Ha sido útil esta solución?