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?

Captain Stack
fuente

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

Stewie
fuente
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>
couzzi
fuente
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.

shaunhusain
fuente
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>
Rizo
fuente
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.

fdrv
fuente
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>
Rajkiran Shetty
fuente
-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.

Matt Saunders
fuente
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