角度滤波器:如何预滤波,因此角度滤波器仅考虑整个数据对象的一部分

时间:2015-03-26 08:05:21

标签: javascript angularjs angularjs-ng-repeat ng-options angular-filters

我有一个包含多列的大型数据表(从json api获取数据),并希望实现多个过滤器,执行以下操作:

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

    我的searchFilter工作正常,但我不确定如何连接columnFilter并使searchFilter仅适用于所选的数据部分。

    所以,我想说我只想看到包含世界“蓝色”的描述。

    如何绑定这两个过滤器并使其工作?

    以下是我的一些代码:

      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>
    

    以及指向工作人员的链接:http://plnkr.co/edit/TddllGiey0RmCx18eVdd?p=preview

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

    我有一个大数据表

    如果我理解得很好,你就明确指出,因为性能是个大问题。

    有一篇好文章揭示了这两种解决方案之间的差异: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;
      };
    });
    

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

答案 2 :(得分:0)

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

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