【问题标题】:filter is really slow on ng-repeat in angularjs过滤器在angularjs中的ng-repeat上真的很慢
【发布时间】:2017-05-15 09:54:09
【问题描述】:

我正在使用 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

如您所见,过滤器可以正常工作,但速度真的很慢。有没有更好的方法来做到这一点并加快速度?在过滤器文本框中输入时,我按下键盘上的键后会有延迟。

【问题讨论】:

  • 当您过滤如此大的数据集时,最好在服务器端而不是客户端进行这项工作。
  • 嗯,表中有 5000 行。您应该尝试批量调用或分页。如果您将呼叫(api url)更改为用户并按 id 过滤,它相当快
  • 您可以获得的一个快速收获是将所有 3 个组合成一个过滤器对象。将您的 ng-model 属性更改为该过滤器对象上与您要过滤的属性匹配的属性。

标签: javascript angularjs


【解决方案1】:

每个过滤器函数都会遍历您的数据一次。因此,如果您有 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 倍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 2014-05-02
    相关资源
    最近更新 更多