Limitar el número de resultados mostrados cuando se usa ngRepeat


148

Encuentro los tutoriales de AngularJS difíciles de entender; este me está guiando en la construcción de una aplicación que muestra teléfonos. Estoy en el paso 5 y pensé que, como experimento, trataría de permitir a los usuarios especificar cuántos les gustaría que se les mostrara. 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>

He agregado esta línea donde los usuarios pueden ingresar cuántos resultados desean 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, se mostrarán 5. Todo lo que quiero hacer es leer el número en esa entrada desde la vista, y ponerlo en la data.splicelínea. He intentado con y sin comillas, y tampoco funciona. ¿Cómo hago esto?

Respuestas:


345

Un poco más "Angular way" sería usar el limitTofiltro directo , como lo proporciona Angular de forma nativa:

<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
Vale la pena señalar, y ahorrarle a alguien más unos minutos, que si está usando "seguimiento por" DEBE ser el último después de los filtros.
stephan.com

3
¿Hay alguna manera de obtener la cantidad de elementos disponibles cuando se usa filter y limitTo? Me gustaría usar, limitTopero proporcionar un botón "cargar más" para aumentar el límite. Esto solo debe mostrarse si hay más registros disponibles.
Tim Büthe

¿Qué es filter:query?
bigpony

@defmx por la pregunta del OP, queryproviene deSearch: <input ng-model="query">
jusopi

45

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>

2
Sospecho que esto sería menos eficiente que el uso limitToFilter si se trata de una gran variedad, ya que cada elemento tiene presumiblemente para ser evaluado
rom99

3
Tuve un escenario en el que quería mostrar 6 elementos de una matriz de respaldo de mucho más. El uso ng-if="$index < 6"me permitió mostrar solo los primeros 6 mientras mantenía la matriz completa de búsqueda (tengo un filtro combinado con un campo de búsqueda).
Jeroen Vannevel

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

@ Jek-fdrv: no, ng-ifen este caso, no representará el elemento DOM del repetidor cuyo valor $indexsea ​​mayor que 3. si $indexen el repetidor es 0, 1, or 2, la condición es truey se crean los nodos DOM. ng-ifdifiere ng-hideen el sentido de que los elementos no se agregan al DOM.
couzzi 01 de

2

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 colocó el reloj fuera del controlador, debería haber estado dentro.


2

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

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

1

Esto funciona mejor en mi caso si tiene un objeto o una matriz multidimensional. Solo mostrará los primeros elementos, otros se ignorarán en 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 en lo que quieras.


0

Use limitTo filter 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>

-3

Otra forma (y creo que mejor) de lograr esto es interceptar los datos. limitTo está bien, pero ¿qué pasa si está limitando a 10 cuando su matriz realmente 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 hacerlo 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 hacerlo usted mismo. github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99

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

1
Sí, lo que está haciendo es exponer una nueva matriz a la vista (realmente no lo consideraría como 'enviar' nada a ningún lado). Si solo estaba interesado en los primeros 10 elementos en los datos y no se hace referencia a los datos en ningún otro lugar, hacerlo de esta manera podría reducir la huella de la memoria (suponiendo que los datos se puedan recolectar basura). Pero si aún conserva una referencia data, esto no es más eficiente que usar limitTo.
rom99
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.