จำกัด จำนวนผลลัพธ์ที่แสดงเมื่อใช้ ngRepeat


148

ฉันพบว่าบทเรียน AngularJSยากที่จะเข้าใจ อันนี้ฉันกำลังเดินผ่านการสร้างแอพที่แสดงโทรศัพท์ ฉันอยู่ในขั้นตอนที่ 5และฉันคิดว่าเป็นการทดลองฉันพยายามอนุญาตให้ผู้ใช้ระบุจำนวนที่ต้องการให้แสดง มุมมองมีลักษณะดังนี้:

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

ฉันได้เพิ่มบรรทัดนี้ซึ่งผู้ใช้สามารถป้อนจำนวนผลลัพธ์ที่ต้องการแสดง:

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

นี่คือตัวควบคุมของฉัน:

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

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

บรรทัดสำคัญคือ:

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

ฉันสามารถเขียนโค้ดจำนวนมากเพื่อแสดงจำนวนโทรศัพท์ที่ควรแสดง หากฉันใส่5เข้าไปจะมีการแสดง 5 สิ่งที่ฉันต้องการจะทำคืออ่านตัวเลขในอินพุตนั้นจากมุมมองและวางลงในdata.spliceบรรทัด ฉันได้ลองใช้ทั้งไม่ใส่เครื่องหมายคำพูดและไม่ได้ผล ฉันจะทำสิ่งนี้ได้อย่างไร

คำตอบ:


345

"วิธีเชิงมุม" อีกเล็กน้อยจะใช้limitToตัวกรองที่ตรงไปตรงมาซึ่งจัดทำโดย 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


54
มันคุ้มค่าที่จะชี้ให้เห็นและช่วยคนอื่นสักครู่ - ถ้าคุณใช้ "ติดตามโดย" จะต้องอยู่หลังตัวกรอง
stephan.com

3
มีวิธีรับจำนวนรายการที่พร้อมใช้งานหรือไม่เมื่อใช้ตัวกรองและ จำกัด ไปยัง ฉันต้องการใช้limitToแต่ให้ปุ่ม "โหลดเพิ่มเติม" เพื่อเพิ่มขีด จำกัด สิ่งนี้จะปรากฏขึ้นหากมีระเบียนเพิ่มเติมเท่านั้น
ทิมBüthe

คือfilter:queryอะไร
bigpony

@defmx ตามคำถามของ OP queryมาจากSearch: <input ng-model="query">
jusopi

45

สายไปงานเลี้ยงเล็กน้อย แต่มันก็ใช้ได้กับฉัน หวังว่าคนอื่นจะพบว่ามีประโยชน์

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

2
ฉันสงสัยว่าสิ่งนี้จะมีประสิทธิภาพน้อยกว่าการใช้ limitToFilter ถ้าเป็นอาร์เรย์ขนาดใหญ่เพราะทุกรายการจะต้องมีการประเมิน
rom99

3
ฉันมีสถานการณ์ที่ฉันต้องการแสดง 6 รายการจากอาเรย์สำรองอีกมากมาย การใช้ng-if="$index < 6"อนุญาตให้ฉันแสดงเฉพาะ 6 รายการแรกเท่านั้นในขณะที่รักษาอาร์เรย์ทั้งหมดที่ค้นหาได้ (ฉันมีตัวกรองร่วมกับเขตข้อมูลการค้นหา)
Jeroen Vannevel

ไม่ จำกัด ซึ่งจะซ่อนผลลัพธ์ทั้งหมดหากนับมากกว่า 3
fdrv

@ เจ๊ก-fdrv - ไม่มีng-ifในกรณีนี้จะไม่ทำให้องค์ประกอบ DOM ของทวนที่มีเป็นจำนวนมากกว่า$index 3ถ้า$indexใน repeater คือ0, 1, or 2เงื่อนไขคือtrueและโหนด DOM ถูกสร้างขึ้น ng-ifแตกต่างจากng-hideในแง่ที่องค์ประกอบจะไม่ถูกเพิ่มใน DOM
couzzi

2

เก็บข้อมูลทั้งหมดของคุณในตอนแรก

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

แก้ไขโดยไม่ได้ตั้งใจวางนาฬิกาภายนอกตัวควบคุมมันควรจะอยู่ภายใน


2

นี่เป็นอีกวิธีหนึ่งในการ จำกัด ตัวกรองของคุณบน html ตัวอย่างเช่นฉันต้องการแสดงรายการ 3 รายการในเวลาที่ฉันจะใช้limitTo: 3

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

1

สิ่งนี้จะทำงานได้ดีขึ้นในกรณีของฉันหากคุณมีวัตถุหรืออาร์เรย์หลายมิติ มันจะแสดงเฉพาะรายการแรกเท่านั้นส่วนอื่นจะถูกละเว้นในการวนซ้ำ

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

เปลี่ยน 5 ในสิ่งที่คุณต้องการ


0

ใช้ตัวกรอง limitTo เพื่อแสดงผลลัพธ์จำนวน จำกัด ใน ng-repeat

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

-3

อีกวิธีหนึ่ง (และฉันคิดว่าดีกว่า) ในการบรรลุเป้าหมายนี้คือการดักข้อมูลจริง ๆ limitTo ไม่เป็นไร แต่ถ้าคุณ จำกัด 10 ตัวเมื่ออาร์เรย์ของคุณมีจริงพัน

เมื่อเรียกบริการของฉันฉันทำสิ่งนี้

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

สิ่งนี้ จำกัด สิ่งที่ถูกส่งไปยังมุมมองดังนั้นควรมีประสิทธิภาพที่ดีกว่าการทำสิ่งนี้ในส่วนหน้า


การนำไปใช้ของ limitTo ใช้ array.slice () อย่างไรก็ตามความแตกต่างใด ๆ ในขนาดของอาเรย์ควรมีความแตกต่างด้านประสิทธิภาพเช่นเดียวกับที่ทำด้วยตัวคุณเอง github.com/angular/angular.js/blob/master/src/ng/filter/…
rom99

แต่ limitTo ไม่ได้ จำกัด ข้อมูลที่ส่งไปยังมุมมองจริง ๆ ในขณะที่ทำอย่างนี้ ฉันทดสอบสิ่งนี้โดยใช้ console.log ()
Matt Saunders

1
ใช่สิ่งที่คุณกำลังทำคือการเปิดเผยอาร์เรย์ใหม่ให้กับมุมมอง หากคุณสนใจเฉพาะข้อมูล 10 รายการแรกเท่านั้นและไม่มีการอ้างอิงข้อมูลในที่อื่นการทำเช่นนี้อาจช่วยลดการใช้พื้นที่หน่วยความจำ แต่ถ้าคุณยังคงอ้างอิงถึงdataอยู่นี่ก็ไม่มีประสิทธิภาพมากกว่าการใช้ limitTo
rom99
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.