Angular 过滤器:如何预过滤 angular 过滤器只考虑整个数据对象的一部分

Angular Filters: How to pre-filter so angular filters consider only a partial of the whole data object

我有一个大数据 table(它从 json api 获取数据)有多个列,我想实现多个过滤器来执行以下操作:

  1. select 应考虑哪个数据列的选项(包含 thead 选项的下拉列表)[my columnFilter] 然后
  2. 用于过滤特定数据部分的输入字段 [my searchFilter]

我可以使用 searchFilter,但我不确定如何连接 columnFilter 并使 searchFilter 仅适用于 selected 数据部分。

假设我只想看到包含世界 "blue" 的描述。

我如何绑定这两个过滤器并使它起作用?

这是我的一些代码:

  Select data column:
  <select ng-model="columnFilter" ng-options="heading for heading in headings">
  </select>
</div>
<div class="col-sm-12">
   Filter selection: <input type='text' ng-model="searchFilter" />
</div>
<table class="table table-bordered">
    <thead>
      <tr>
        <th>URL</th>
        <th>Title</th>
        <th>Traffic</th>
        <th>Description</th>
        <th>ID</th>
      </tr>
  </thead>
  <tbody ng-repeat="url in urls | filter:searchFilter">
    <tr>
      <td>{{url.url}}</td>
      <td>{{url.title}}</td>
      <td>{{url.traffic}}</td>
      <td>{{url.descr}}</td>
      <td>{{url.id}}</td>
    </tr>
    </tbody>
</table>

和一个 link 给一个正在工作的 plunker:http://plnkr.co/edit/TddllGiey0RmCx18eVdd?p=preview

直接从创建自定义过滤器的 angular 页面查看此示例。 https://docs.angularjs.org/guide/filter

您可以在此处看到,您可以创建一个接受 2 个输入、实际对象和一个参数的过滤器。通过将列名称作为参数传递,您可以缩小对正确行的搜索范围。

我建议您像这样编写简单的自定义过滤器。

.filter('myfilter', function(){
  return function(input, column, text){
    if (!input || !column || !text) return input;
    return input.filter(function(item){
      var value = item[column.toLowerCase()];
      if (!value)return false;
      return value.indexOf(text)>-1;
    });
  };
});

您可以在 html 中使用此过滤器。

ng-repeat="url in urls | myfilter:columnFilter:searchFilter"

This is plunker.

据我所知angular,有两种主要方法可以解决您的问题。

  1. 定义自定义过滤器
  2. 定义一个函数来过滤您的数据并使用 ng-show 或 ng-hide 调用它

I got a large data table

如果我理解得很好,你指定那个,因为性能是一个大问题。

有一篇很好的文章揭示了这两种解决方案之间的差异:http://www.bennadel.com/blog/2487-filter-vs-nghide-with-ngrepeat-in-angularjs.htm

由于性能对你来说可能真的很重要,我建议你采用第二种方法。

在您看来:

<tbody ng-repeat="url in urls" ng-show="filterUrl(url)">

在你的控制器中:

$scope.searchFilter = "";
$scope.columnFilter = $scope.headings[5];

$scope.filterUrl = function(url){ 
  if(!$scope.searchFilter || $scope.searchFilter == "")
    return url;
  var searchFilter= $scope.searchFilter.toLowerCase();
  var trafficString = url.traffic.toString();
  var idString = url.traffic.toString();
  switch($scope.columnFilter){
    case $scope.headings[0]:
      return url.title.toLowerCase().indexOf(searchFilter) != -1;
    case $scope.headings[1]:
      return url.url.toLowerCase().indexOf(searchFilter) != -1;
    case $scope.headings[2]:
      return trafficString.indexOf(searchFilter) != -1;
    case $scope.headings[3]:
      return url.descr.toLowerCase().indexOf(searchFilter) != -1;
    case $scope.headings[4]:
      return idString.indexOf(searchFilter) != -1;
    case $scope.headings[5]: 
      return url.title.toLowerCase().indexOf(searchFilter) != -1 ||
      url.url.toLowerCase().indexOf(searchFilter) != -1 ||
      trafficString.indexOf(searchFilter) != -1 ||
      url.descr.toLowerCase().indexOf(searchFilter) != -1 ||
      idString.indexOf(searchFilter) != -1;
  }
};

更新: 如果选择第一种方法:

在您看来:

 <tbody ng-repeat="url in urls | filterByColumn: searchFilter :columnFilter">

过滤器:

app.filter('filterByColumn', function(){
  return function(urls, text, columnFilter){
    var processed = [];
     if(!text || text == "")
        return urls;
    urls.forEach(function(url){
      var searchFilter= text.toLowerCase();
      var trafficString = url.traffic.toString();
      var idString = url.traffic.toString();
      switch(columnFilter){
        case "Title":
          if( url.title.toLowerCase().indexOf(searchFilter) != -1)
            processed.push(url);
          break;
        case "Url":
          if(url.url.toLowerCase().indexOf(searchFilter) != -1)
            processed.push(url);
          break;
        case "Traffic":
          if(trafficString.indexOf(searchFilter) != -1)
            processed.push(url);
          break;
        case "Description":
          if(url.descr.toLowerCase().indexOf(searchFilter) != -1)
            processed.push(url);
          break;
        case "Id":
          if( idString.indexOf(searchFilter) != -1)
            processed.push(url);
          break;
        case "All": 
          if( url.title.toLowerCase().indexOf(searchFilter) != -1 ||
          url.url.toLowerCase().indexOf(searchFilter) != -1 ||
          trafficString.indexOf(searchFilter) != -1 ||
          url.descr.toLowerCase().indexOf(searchFilter) != -1 ||
          idString.indexOf(searchFilter) != -1)
            processed.push(url);
          break;
      }
    });
    return processed;
  };
});

这是一个 plunkr:http://plnkr.co/edit/xCwI2AURFpvb6xHgYHxS?p=preview