如何为ng-repeat指定自定义过滤器功能?

Ale*_*gli 3 angularjs

我正在尝试使用ng-repeat的自定义过滤器函数,因为我的过滤器值是一个复杂的对象.我正在使用angularJS v1.5并遵循以下文档:https://code.angularjs.org/1.5.0/docs/api/ng/filter/filter

文档说你可以指定一个这样的表达式:{{filter_expression | filter:expression:comparator}}并且使用两个参数调用比较器函数,即数组中的实际对象和谓词值.我的比较器函数对于实际对象始终具有"未定义".我尝试使一切尽可能简单,它仍然发送未定义的实际对象.

$scope.athletes = [
    {
      "name":"first",
      "tags":[
      "Offense"]
    },
    {
      "name":"two",
      "tags":[
      "Defense"]
    },
    {
      "name":"three",
      "tags":[
      "Special Teams"]
    },
    {
      "name":"four",
      "tags":[
      "Offense"]
    }
    ];

    $scope.athletesInFunction = [];

    $scope.doesAthleteHaveTag = function(athlete,filterValue){
      if (athlete) {
      $scope.athletesInFunction.push(athlete);
      if (athlete.tags.indexOf(filterValue) > -1) {
        return true;
      }
      }
      return false;
    };
Run Code Online (Sandbox Code Playgroud)

HTML文件:

<div ng-repeat="athlete in athletes | filter:filterValue:doesAthleteHaveTag">
        <div>Name: {{athlete.name}}</div>
      </div>
Run Code Online (Sandbox Code Playgroud)

示例plunkr:https://plnkr.co/edit/lk26tFFgux2sLpuke56m p = preview

我究竟做错了什么?如何让它在实际的数组对象中发送以进行过滤?

编辑:我应该更清楚我的问题.我的问题是文档是否有效,以及使用自定义过滤器功能的推荐方法是什么.我目前只使用表达式函数,因为过滤谓词是范围广泛的变量,我可以在我的表达式函数中轻松访问它.我不知道这是否更好,更糟或与使用比较器功能相同,或者如果最好只编写一个自定义过滤器,如其中一个答案所述.

bri*_*bri 8

为了创建一个自定义AngularJs过滤器,它接受一个参数,则需要将其定义为一个过滤器这样.这个想法很简单:过滤器返回你的数组的FILTERED版本(这样,你不会通过对你正在观察的根数组的大量更改来破坏摘要周期).

在你的情况下:

1.创建一个过滤器

app.filter('hasTag', function() {
  return function(items, tagName) {
    var filtered = [];
    angular.forEach(items, function(el) {
      if(el.tags && el.tags.indexOf(tagName)>-1) {
        filtered.push(el);
      }
    });
    return filtered;
  }
});
Run Code Online (Sandbox Code Playgroud)

2.更改过滤器参数

<div ng-repeat="athlete in athletes | hasTag:'Defense'">
Run Code Online (Sandbox Code Playgroud)

应该这样做.

选项#2 - 更改ng-repeat以使用过滤后的数组.

因为我的大部分过滤器都非常"特定于控制器" - 我倾向于使用过滤后的数组作为我的ng-repeat源.

<div ng-repeat="athlete in AthletesByRole('Defense')">
Run Code Online (Sandbox Code Playgroud)

这种方法让我自己在控制器级别控制缓存......我发现它更容易阅读/维护(因为AthletesByRole()是控制器内的一个函数,而不是一些随机的"其他"js文件中的过滤函数,我写完后6个月必须跟踪)...只是需要考虑的额外想法.