Limitando o número de resultados exibidos ao usar ngRepeat

148

Acho os tutoriais do AngularJS difíceis de entender; este está me orientando na criação de um aplicativo que exibe telefones. Estou na etapa 5 e, como experiência, pensei em tentar permitir que os usuários especifiquem quantos gostariam de mostrar. A visualização é assim:

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

Adicionei esta linha em que os usuários podem inserir quantos resultados desejam:

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

Aqui está o meu 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;
}

A linha importante é:

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

Posso codificar em um número para representar quantos telefones devem ser mostrados. Se eu colocar 5, 5 serão mostrados. Tudo o que quero fazer é ler o número nessa entrada a partir da visualização e colocá-lo na data.splicelinha. Eu tentei com e sem aspas, e nem trabalho. Como eu faço isso?

Capitão Stack
fonte

Respostas:

345

Um pouco mais "Maneira angular" seria usar o limitTofiltro direto , como fornecido originalmente pela 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
fonte
54
Vale ressaltar - e salvar alguém por alguns minutos - que, se você estiver usando "rastrear", DEVE ser a última após os filtros.
stephan.com
3
Existe uma maneira de obter o número de itens disponíveis ao usar filter e limitTo? Eu gostaria de usar, limitTomas forneço um botão "carregar mais" para aumentar o limite. Isso só deve ser exibido se houver mais registros disponíveis.
Tim Buthe
O que é filter:query?
bigpony 28/01
@defmx de acordo com a pergunta do OP, queryvem deSearch: <input ng-model="query">
jusopi 12/03/16
45

Um pouco tarde para a festa, mas isso funcionou para mim. Espero que alguém ache útil.

<div ng-repeat="video in videos" ng-if="$index < 3">
    ...
</div>
couzzi
fonte
2
Eu suspeito que isso seria menos eficiente do que usar limitToFilter se for uma grande variedade, porque cada item tem presumivelmente para ser avaliado
rom99
3
Eu tive um cenário em que queria mostrar 6 itens de uma variedade de muito mais. Usar ng-if="$index < 6"me permitiu mostrar apenas os 6 primeiros, mantendo toda a matriz pesquisável (eu tenho um filtro combinado com um campo de pesquisa).
Jeroen Vannevel
Não é um limite, é ocultar todo o resultado se contar mais que 3.
fdrv
@ Jek-fdrv - Não, ng-ifneste caso, não renderizará o elemento DOM do repetidor cujo valor $indexé maior que 3. se $indexno repetidor 0, 1, or 2, a condição é truee os nós DOM são criados. ng-ifdifere ng-hideno sentido de que os elementos não são adicionados ao DOM.
couzzi
2

armazene todos os seus dados 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)
  });
}

A EDIT acidentalmente colocou o relógio fora do controlador, que deveria estar dentro.

shaunhusain
fonte
2

aqui está uma outra maneira de limitar seu filtro em html, por exemplo, eu quero exibir 3 listas de cada vez do que usarei limitTo: 3

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

Isso funciona melhor no meu caso, se você tiver um objeto ou matriz multidimensional. Ele mostrará apenas os primeiros itens, outros serão apenas ignorados em loop.

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

Mude 5 para o que você deseja.

fdrv
fonte
0

Use o filtro limitTo para exibir um número limitado de resultados em ng-repeat.

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

Outra (e acho melhor) maneira de conseguir isso é realmente interceptar os dados. limitTo está bom, mas e se você estiver limitando a 10 quando sua matriz realmente contém milhares?

Ao ligar para o meu serviço, simplesmente fiz o seguinte:

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

Isso limita o que é enviado para a exibição, portanto, deve ser muito melhor para o desempenho do que fazer isso no front-end.

Matt Saunders
fonte
A implementação de limitTo usa array.slice () de qualquer maneira, qualquer diferença no tamanho da matriz deve ter a mesma diferença no desempenho do que você mesmo. github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99
mas limitTo na verdade não limita os dados enviados para a exibição, enquanto faz isso dessa maneira. Eu testei isso usando console.log ().
Matt Saunders
1
Sim, o que você está fazendo é expor uma nova matriz à exibição (eu realmente não pensaria nisso como 'enviar' algo para qualquer lugar). Se você estava interessado apenas nos 10 primeiros itens em dados, e os dados não são referenciados em nenhum outro lugar, fazê-lo dessa maneira pode reduzir o consumo de memória (supondo que os dados possam ser coletados com lixo). Mas se você ainda mantém uma referência data, isso não é mais eficiente do que usar limitTo.
rom99