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

もう少し「Angular way」は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 2015

3
filterとlimitToを使用するときに利用可能なアイテムの数を取得する方法はありますか?使用したいのですlimitToが、制限を増やすために「もっと読み込む」ボタンを提供します。これは、より多くのレコードが利用可能な場合にのみ表示されます。
TimBüthe2015年

なにfilter:query
ビッグポニー2016年

OPの質問ごとの@defmxは、次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

JEK-FDRV @ -いや、ng-ifこの場合には、リピータのDOM要素表示されません$index以上であるが3。あれば$indexリピーターにある0, 1, or 2、条件があるtrueとDOMノードが作成されます。要素がDOMに追加されないというng-if点で異なります。ng-hide
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)
  });
}

EDITが誤って時計をコントローラーの外に置いていたはずです。


2

これは、htmlでフィルターを制限する別の方法です。たとえば、limitTo:3を使用するよりも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

ng-repeatで限られた数の結果を表示するには、limitToフィルターを使用します。

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