2013-07-14 16 views
131

Jestem ogromnym AngularJS n00b i znajduję nawet tutorials trudny do zrozumienia. Ten samouczek prowadzi mnie przez budowanie aplikacji wyświetlającej telefony. Jestem na step 5 i pomyślałem, że jako eksperyment chciałbym zezwolić użytkownikom na określenie, ile chcieliby być wyświetleni. Widok wygląda następująco:ngRepeat - ograniczenie liczby wyświetlanych wyników

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

Dodałem tę linię, aby użytkownicy mogli wejść ile wyniki chcą pokazany:

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

Oto mój kontroler:

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

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

Ważną linia to:

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

Mogę zakodować kod w liczbie, aby pokazać ile telefonów powinno być pokazanych. Jeśli włożę 5, pojawi się 5. Wszystko, co chcę zrobić, to odczytać numer z tego wejścia z widoku i umieścić go w wierszu data.splice. Próbowałem z cytatami i bez nich, a także nie pracowałem. Jak mam to zrobic?

Odpowiedz

315

Nieco bardziej "kątowy sposób" byłoby użyć prostego limitTo filtr, jak oryginalnie dostarczone przez kątowa:

<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

+43

Warto wskazać - i oszczędzić komuś jeszcze kilka minut - że jeśli używasz "track by" MUSI być ostatni po filtrach. –

+3

Czy istnieje sposób na uzyskanie liczby dostępnych elementów przy użyciu filtru i limitu? Chciałbym użyć 'limitTo', ale proszę podać przycisk" załaduj więcej ", aby zwiększyć limit. Powinno to być wyświetlane tylko wtedy, gdy dostępnych jest więcej rekordów. –

+2

@ TimBüthe Wypróbuj to rozwiązanie: http://stackoverflow.com/a/19665313/1095616 – Stewie

2

przechowywać wszystkie swoje dane początkowo

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 przypadkowo umieścić zegarek zewnątrz regulatora powinno to być w środku.

41

Trochę późno do partii, ale to działało dla mnie. Mam nadzieję, że ktoś inny uzna to za przydatne.

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

Podejrzewam, że byłoby to mniej wydajne niż użycie limituToFilter, jeśli jest to duża tablica, ponieważ każdy element prawdopodobnie musi być oceniany – rom99

+3

Miałem scenariusz, w którym chciałem pokazać 6 przedmiotów z tablicy o wiele więcej. Użycie 'ng-if =" $ index <6 "' pozwoliło mi pokazać tylko pierwsze 6, zachowując całą przeszukiwalność tablicy (mam filtr połączony z polem wyszukiwania). –

+0

To nie jest limit, to ukryj cały wynik, jeśli policzysz więcej niż 3. – fdrv

-3

Innym (i myślę, że lepiej) sposobem osiągnięcia tego celu jest faktycznie przechwytują dane. limitTo jest w porządku, ale co jeśli ograniczasz się do 10, gdy twoja macierz zawiera tysiące?

Dzwoniąc moją usługę po prostu to zrobił:

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

Ogranicza to, co jest wysyłane do widzenia, więc powinno być dużo lepiej niż robi to wydajność na front-end.

+0

Implementacja limitu używa tablicy array.slice(), jednak każda różnica w wielkości tablicy powinna mieć tę samą różnicę w wydajności, co wykonanie samodzielnie. https://github.com/angular/angular.js/blob/master/src/ng/filter/limitTo.js – rom99

+0

, ale limitTo w rzeczywistości nie ogranicza danych wysyłanych do widoku, a robi to w ten sposób. Przetestowałem to za pomocą console.log(). –

+1

Tak, to co robisz, to wystawianie nowej tablicy na widok (nie myślałbym o tym tak, jakbym coś "wysłała" gdziekolwiek). Jeśli interesowały Cię tylko pierwsze 10 pozycji w danych, a dane nie są nigdzie indziej przywoływane, robienie tego w ten sposób może zmniejszyć ślad pamięci (zakładając, że dane mogą zostać zebrane). Ale jeśli nadal zachowujesz odniesienie do "danych", nie jest to bardziej efektywne niż użycie metody limitTo. – rom99

1

Działa to lepiej w moim przypadku, jeśli masz obiekt lub tablicę wielowymiarową. Pokaże tylko pierwsze elementy, inne będą po prostu ignorowane w pętli.

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

Zmień 5, co chcesz.

0

Użyj filtru limitTo, aby wyświetlić ograniczoną liczbę wyników w powtórzeniu ng.

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