按值数组筛选Angular

4

我正在尝试使用值数组来筛选项目列表。到目前为止,我已经成功地过滤了表中的多个字段,但我无法使用表中一个列内的多个值进行过滤。这个plunker示例展示了如何使用该过滤器对象。

$scope.filters = {
   user:{
     name:"John"
   },
   status:{
     name: "Approved" 
   }
};

然而,我试图根据这个过滤器对象生成一个已过滤的列表:
$scope.filters = {
  user:{
    name:"John"
  },
  status:{
    name: ["Approved", "For Review"] 
  }
};

我希望能够得到一个名单,该名单包括所有状态为“已批准”或“待审核”的Johns用户。

是否可以使用Angular的“filter”过滤器来实现此目的,还是需要使用自定义过滤器?


1
我认为这只能通过使用自定义筛选器来完成。我在文档中搜索了一下,但没有找到任何地方说明在筛选器中使用两个表达式的方法。因此,我认为您应该只使用自定义筛选器来完成它。 - v1shnu
3个回答

3
你需要使用自定义过滤器来实现这个功能。或者你也可以分别按状态数组和用户名进行过滤:
$scope.filtered = $filter('filter')($scope.users, {user: $scope.filters.user}).filter(function(user) {
    return $scope.filters.status.name.indexOf(user.status.name) > -1;
});

演示: http://plnkr.co/edit/KcP6bLujFnxFPXrVRfUp?p=preview

这真的很棒! - v1shnu
这看起来暂时能解决问题。显然,这个功能在之前的 Angular 版本中是正常的,但在升级到 1.3 版本后出现了问题。https://github.com/angular/angular.js/issues?utf8=%E2%9C%93&q=filterFilter。感谢您的帮助。 - abyrne85

2

我认为一个好的方法是将有关某个属性的所有过滤逻辑封装到过滤器本身中,并根据其功能命名该过滤器。在这个示例中,您有两个过滤器:按用户和按状态。恰巧当前您只对这些过滤器中的每个过滤器进行了一个属性(名称)的过滤,但将来您可能会有多个属性可供用户和状态筛选。

考虑以上情况,我建议为您的模块提供以下两个过滤器:

app.filter('byStatus', function() {
  return function(items, filter) {
    var out = [];
    //status.name
    angular.forEach(items, function(item) {
      if (filter.name.constructor != Array) {
        if (filter.name == item.status.name) {
          out.push(item);
        }
      } else if (filter.name.indexOf(item.status.name) > -1) {
        out.push(item);
      }
    });
    return out;
  };
});
app.filter('byUser', function() {
  return function(items, value) {
    var out = [];
    //user.name
    angular.forEach(items, function(item) {
      if (item.user.name.indexOf(value.name) > -1) {
        out.push(item);
      }
    });
    return out;
  };
});

Plunker: http://plnkr.co/edit/g3ERmycps8Fg6trE1NfN?p=preview

这里有两个$filter调用,但没关系,我一直鼓励代码的清晰度优先于性能。


这是一个非常好的解决方案,但我在plunkr中放置的数据只是整个数据集的一个小样本。理想情况下,我可以针对任何字段进行过滤,而不是为特定字段创建定制的过滤器。然而,对于较小和更静态的数据,我确实喜欢这种方法。我将在应用程序的另一个区域实现它。谢谢。 - abyrne85

1

HTML:

<table id="searchTextResults">
  <tr><th>Name</th><th>Phone</th><th>Status</th></tr>
  <tr ng-repeat="friend in friends | filter: myFilter">
    <td>{{friend.user.name}}</td>
    <td>{{friend.phone}}</td>
    <td>{{friend.status.name}}</td>
  </tr>
</table>

自定义过滤器:-
$scope.myFilter = function (item) { 
    return item.status.name === 'For Review' || item.status.name === 'Approved'; 
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接