将当前元素传递给ng-repeat中的自定义过滤器

时间:2014-01-17 13:44:15

标签: javascript angularjs

是否可以将ng-repeat的当前元素传递给自定义过滤器?

以某种方式(HTML):

<ul>
    <li ng-repeat="row in rows | myFilter:row:anotherArgument>{{row}}</li>
</ul>

和(Javascript):

angular.module('myApp', [])
    .filter('myFilter', function() {
        return function(items, item, arg) {
            // Do something here
        }
    });

我正在处理的数据看起来像这样(简化):

[
    {
        "id":"52d7d22867960cb905e1c5b3",
        "label":"Model A",
        "children":[
            {
                "id":"52d7d22967960cb905e1c5bf",
                "type":"Page",
                "label":"Sample Page A",
                "class":"page",
                "children":[...],
                "watched":false
            },
            {...},
            {
                "id":"52d7d22967960cb905e1c5bd",
                "label":"Page",
                "class":"type"
            }
        ],
        "class":"model",
        "watched":false
    },
    {...}
]

所以基本上我有一个树状的结构,在第一层,可能有一个或多个元素"class":"type"。嵌套数据由Nick Perkins的angular-bootstrap-nav-tree指令处理。 我只想显示"watched":true的元素。问题当然是"class":"type"的元素没有watched属性。

TL;博士
过滤掉"watched":false,但保留"class":"type"

元素

3 个答案:

答案 0 :(得分:3)

不是因为您正在使用它,但有一些方法可以整体处理行并单独使用。

如果您需要在ng-repeat内容之前访问行的元素,则应该为整个数组编写过滤器:

<ul>
  <li ng-repeat="row in rows | myFilter:anotherArgument"> ... </li>
</ul>

在filter-definition中,只需使用整个数组:

angular.module('myApp', []).filter('myFilter', function() {
  return function(items, anotherArgument) {
    // here you can access each argument as you like
    items.forEach(function(item) { 
      ...
    });
    return items;
  };
});

这样做的主要原因是,在迭代数组并且数组本身是整个 FilterChain 结果之前,row不存在。想想阵列就像这样:

ng-repeat="row in (row | filter1 | filter2 | ...)"

但根据您myFilter的目的,您可能只想在重复内容中应用该过滤器。

<ul>
  <li ng-repeat="row in rows">
    {{row | myFilter:anotherArgument}}
  </li>
<ul>

如果您使用第一种方法,我建议您在将数组传递给ng-repeat之前在控制器中准备数组。任何绑定(如{{...}}ng-bindng-repeat)内的过滤器链越复杂,就必须在每个角度的摘要周期内计算得越多。这可能会导致应用程序变慢。

更新根据更新的问题:

在您的情况下,我猜自定义过滤器可能如下所示:

angular.module('myApp', []).filter('mySpecificFilter', function() {
  return function(items) {
    return items.filter(function(element) {
      return element.watched || element['class'] === 'type';
    }
  }
});

答案 1 :(得分:0)

刚刚做错了什么?

<ul>
    <li ng-repeat="row in rows">{{row | myFilter:anotherArgument}}</li>
</ul>

答案 2 :(得分:0)

以下是一个示例:

请注意,过滤器的第一个参数是“数据源”(整个列表)。过滤器的目的是过滤数据源。

HTML示例

<ul ng-controller="myCtrl">
    <li ng-repeat="row in friends |myFilter:2:5 ">{{row.name}}</li>
<ul>

Js App和过滤器创建

var myApp = angular.module('myApp',[]);

myApp.filter('myFilter', function() {
        return function(items, begin, end) {                                     

            return items.slice( begin, end);
        }
    });

function myCtrl($scope)
{    
    $scope.friends = [
      {name:'John', age:25, gender:'boy'},
      {name:'Jessie', age:30, gender:'girl'},
      {name:'Johanna', age:28, gender:'girl'},
      {name:'Joy', age:15, gender:'girl'},
      {name:'Mary', age:28, gender:'girl'},
      {name:'Peter', age:95, gender:'boy'},
      {name:'Sebastian', age:50, gender:'boy'},
      {name:'Erika', age:27, gender:'girl'},
      {name:'Patrick', age:40, gender:'boy'},
      {name:'Samantha', age:60, gender:'girl'}
    ];
}