使用 ngRepeat 时限制显示结果的数量

Posted

技术标签:

【中文标题】使用 ngRepeat 时限制显示结果的数量【英文标题】:Limiting number of displayed results when using ngRepeat 【发布时间】:2013-07-12 16:12:29 【问题描述】:

我觉得AngularJS tutorials 很难理解;这个正在引导我构建一个显示手机的应用程序。我在step 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 行中。我试过带引号和不带引号,都不管用。我该怎么做?

【问题讨论】:

【参考方案1】:

这是另一种限制 html 过滤器的方法,例如,我想一次显示 3 个列表,而不是使用 limitTo:3

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

【讨论】:

【参考方案2】:

使用 limitTo 过滤器在 ng-repeat 中显示有限数量的结果。

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

【讨论】:

【参考方案3】:

如果您有对象或多维数组,这在我的情况下效果更好。它只会显示第一个项目,其他将在循环中被忽略。

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

【讨论】:

【参考方案4】:

实现此目的的另一种(我认为更好)方法是实际截取数据。 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/… 但是 limitTo 实际上并没有限制发送到视图的数据,而这样做却可以。我使用 console.log() 对此进行了测试。 是的,你正在做的是将一个新数组暴露给视图(我不会真的认为它是在任何地方“发送”任何东西)。如果您只对数据中的前 10 项感兴趣,并且没有在其他任何地方引用数据,那么这样做可能会减少内存占用(假设数据可以被垃圾收集)。但是,如果您仍然保留对 data 的引用,这并不比使用 limitTo 更有效。【参考方案5】:

稍微更“Angular 方式”的是使用直接由 Angular 提供的 limitTo 过滤器:

<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

【讨论】:

值得指出 - 并为其他人节省几分钟 - 如果您使用“track by”,它必须在过滤器之后。 使用filter和limitTo时有没有办法获取可用项目的数量?我想使用limitTo,但提供“加载更多”按钮来增加限制。仅当有更多可用记录时才应显示。 filter:query 是什么? @defmx 根据 OP 的问题,query 来自 Search: &lt;input ng-model="query"&gt;【参考方案6】:

聚会有点晚了,但这对我有用。希望其他人觉得它有用。

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

【讨论】:

我怀疑如果它是一个大数组,这将比使用 limitToFilter 效率低,因为可能必须评估每个项目 我有一个场景,我想从一个更多的支持数组中显示 6 个项目。使用 ng-if="$index &lt; 6" 允许我只显示前 6 个,同时保持整个数组可搜索(我有一个与搜索字段相结合的过滤器)。 没有限制,如果超过3个则隐藏整个结果。 @Jek-fdrv - 不,ng-if,在这种情况下,不会渲染 $index 大于 3 的转发器的 DOM 元素。如果转发器中的$index0, 1, or 2,则条件为true 并创建DOM 节点。 ng-ifng-hide 的不同之处在于元素添加到 DOM。【参考方案7】:

最初存储所有数据

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 不小心将手表放在了本应在里面的控制器之外。

【讨论】:

以上是关于使用 ngRepeat 时限制显示结果的数量的主要内容,如果未能解决你的问题,请参考以下文章

ngRepeat 暂时显示重复列表

AngularJS - 如何获取 ngRepeat 过滤结果参考

模型更改后ngRepeat不更新

如何限制显示的对象数量?

抓取时如何限制结果数量

twitter typeahead ajax结果未全部显示