Membatasi jumlah hasil yang ditampilkan saat menggunakan ngRepeat

148

Saya menemukan tutorial AngularJS sulit dimengerti; yang satu ini sedang menuntun saya membangun aplikasi yang menampilkan telepon. Saya pada langkah 5 dan saya pikir sebagai percobaan saya akan mencoba untuk memungkinkan pengguna untuk menentukan berapa banyak mereka ingin ditampilkan. Tampilannya seperti ini:

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

Saya telah menambahkan baris ini di mana pengguna dapat memasukkan berapa banyak hasil yang ingin mereka tampilkan:

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

Ini controller saya:

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

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

Garis yang penting adalah:

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

Saya dapat membuat kode dalam angka untuk menunjukkan berapa banyak ponsel yang harus ditampilkan. Jika saya memasukkan 5, 5 akan ditampilkan. Yang ingin saya lakukan adalah membaca angka dalam input dari tampilan, dan memasukkannya ke dalam data.splicebaris. Saya sudah mencoba dengan dan tanpa tanda kutip, dan tidak berhasil. Bagaimana saya melakukan ini?

Kapten Stack
sumber

Jawaban:

345

Sedikit lebih "Angular way" akan menggunakan limitTofilter langsung , seperti yang disediakan oleh 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
sumber
54
Perlu ditunjukkan - dan hemat orang lain beberapa menit - bahwa jika Anda menggunakan "lacak", itu HARUS menjadi yang terakhir setelah filter.
stephan.com
3
Apakah ada cara untuk mendapatkan jumlah item yang tersedia saat menggunakan filter dan limitTo? Saya ingin menggunakan limitTotetapi memberikan tombol "memuat lebih banyak" untuk meningkatkan batas. Ini hanya akan ditampilkan jika lebih banyak catatan tersedia.
Tim Büthe
Apa filter:query?
bigpony
@defmx per pertanyaan OP, queryberasal dariSearch: <input ng-model="query">
jusopi
45

Sedikit terlambat ke pesta, tapi ini berhasil untukku. Semoga orang lain merasakan manfaatnya.

<div ng-repeat="video in videos" ng-if="$index < 3">
    ...
</div>
couzzi
sumber
2
Saya menduga ini akan kurang efisien daripada menggunakan limitToFilter jika array yang besar, karena setiap item mungkin harus dievaluasi
rom99
3
Saya memiliki skenario di mana saya ingin menampilkan 6 item dari berbagai backing. Menggunakan ng-if="$index < 6"memungkinkan saya untuk hanya menampilkan 6 pertama sekaligus menjaga seluruh array dapat dicari (saya memiliki filter yang dikombinasikan dengan bidang pencarian).
Jeroen Vannevel
Ini bukan batas, itu menyembunyikan seluruh hasil jika dihitung lebih dari 3.
fdrv
@ Jek-fdrv - Tidak, ng-ifdalam hal ini, tidak akan membuat elemen DOM dari pengulang yang $indexlebih besar dari 3. jika $indexdalam repeater adalah 0, 1, or 2, kondisinya truedan node DOM dibuat. ng-ifberbeda dari ng-hidedalam arti elemen tidak ditambahkan ke DOM.
couzzi
2

simpan semua data Anda pada awalnya

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 tidak sengaja meletakkan arloji di luar pengontrol yang seharusnya ada di dalamnya.

shaunhusain
sumber
2

di sini adalah cara lain untuk membatasi filter Anda pada html, misalnya saya ingin menampilkan 3 daftar pada waktu daripada saya akan menggunakan limitTo: 3

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

Ini berfungsi lebih baik dalam kasus saya jika Anda memiliki objek atau array multi-dimensi. Ini hanya akan menampilkan item pertama, yang lainnya hanya akan diabaikan dalam lingkaran.

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

Ubah 5 pada apa yang Anda inginkan.

fdrv
sumber
0

Gunakan filter limitTo untuk menampilkan hasil dalam jumlah terbatas di ng-repeat.

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

Cara lain (dan saya pikir lebih baik) untuk mencapai ini adalah benar-benar mencegat data. limitTo baik-baik saja tetapi bagaimana jika Anda membatasi hingga 10 ketika array Anda sebenarnya berisi ribuan?

Saat menelepon layanan saya, saya hanya melakukan ini:

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

Ini membatasi apa yang dikirim ke tampilan, jadi harus jauh lebih baik untuk kinerja daripada melakukan ini di front-end.

Matt Saunders
sumber
Implementasi limitTo menggunakan array.slice (), bagaimanapun, perbedaan ukuran array harus memiliki perbedaan kinerja yang sama dengan melakukannya sendiri. github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99
tetapi limitTo sebenarnya tidak membatasi data yang dikirim ke tampilan, sedangkan melakukannya dengan cara ini tidak. Saya menguji ini menggunakan console.log ().
Matt Saunders
1
Ya, apa yang Anda lakukan adalah mengekspos array baru ke tampilan (saya tidak akan benar-benar menganggapnya sebagai 'mengirim' apa pun di mana saja). Jika Anda hanya tertarik pada 10 item pertama dalam data, dan data tidak direferensikan di tempat lain, melakukannya dengan cara ini dapat mengurangi jejak memori (dengan asumsi data dapat menjadi sampah yang dikumpulkan). Tetapi jika Anda masih menyimpan referensi di datasekitar, ini tidak lebih efisien daripada menggunakan limitTo.
rom99