在angularjs中,过滤器在ng-repeat上非常慢

时间:2017-05-14 23:06:16

标签: javascript angularjs

我使用ng-repeat在表格中显示来自web api的数据。我希望能够使用几个不同的文本框过滤该数据,并选择与表列对齐的列表(总共8个过滤器)。该表通常包含10000多行。以下是我目前正在进行过滤的方式:

HTML:

  <div ng-app="myApp" ng-controller="myCtrl">
    <div class="col-md-12">
      <h1>Multiple Filter Example</h1>
      <hr/>
      <input type="text" placeholder="ID Filter" class="form-control" ng-model="IdFilter" />
      <input type="text" placeholder="Title Filter" class="form-control" ng-model="TitleFilter" />
      <input type="text" placeholder="URL Filter" class="form-control" ng-model="UrlFilter" />
      <br />
      <table class="table">
        <thead>
          <tr>
            <th>Album ID</th>
            <th>ID</th>
            <th>Title</th>
            <th>URL</th>
            <th>Thumbnail URL</th>
          </tr>
        </thead>
        <tbody>
          <tr ng-repeat="item in data | filter:{id:IdFilter} | filter:{title: TitleFilter} | filter:{url: UrlFilter} ">
            <td>{{ item.albumId }}</td>
            <td>{{ item.id }}</td>
            <td>{{ item.title}}</td>
            <td>{{ item.url }}</td>
            <td>{{ item.thumbnailUrl}}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

这是我的JS:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {

  var vm = this;

  vm.IdFilter = "";
  vm.TitleFilter = "";
  vm.UrlFilter = "";

  $http.get("https://jsonplaceholder.typicode.com/photos")
    .then(function(response) {
      $scope.data = response.data;
      console.log($scope.data);
    });


});

plnkr example

正如您所看到的那样,过滤器可以工作,但实际上非常慢。有没有更好的方法来做到这一点并加快速度?当我在键盘上输入一个键后输入过滤器文本框时会出现延迟。

1 个答案:

答案 0 :(得分:0)

每个过滤器函数都会遍历您的数据一次。因此,如果您有8个过滤器和10,000多行,那么您将看到迭代的80,000多行。

我建议您编写一个自定义过滤器,循环遍历10,000多行,并同时应用所有8个过滤器。

app.filter('uberFilter', function() {
  return function(data, filterCriteria) {
    var filtered = [];
    angular.forEach(data, function(item) {
      if( passFilter(item, filterCriteria) {
        filtered.push(item);
      }
    }); 
    return filtered;
  }
})

您的filterCriteria应包含所有过滤条件

filterCriteria = {
    id: ...
  , title: ...
  , url: ...
}

passFilter()应根据所有filterCriteria的标准检查项目

你的html应该将filterCriteria传递给自定义的uberFilter

<tr ng-repeat="item in data | uberFilter:filterCriteria">

这应该有望加快8倍。