将参数传递给angularjs过滤器


99

是否可以将参数传递给filter函数,以便您可以按任何名称进行过滤?

就像是

$scope.weDontLike = function(item, name) {
    console.log(arguments);
    return item.name != name;
};

Answers:


223

实际上,还有另一个(也许是更好的解决方案),您可以使用angular的本机“过滤器”过滤器,并仍将参数传递给自定义过滤器。

考虑以下代码:

<div ng-repeat="group in groups">
    <li ng-repeat="friend in friends | filter:weDontLike(group.enemy.name)">
        <span>{{friend.name}}</span>
    <li>
</div>

为此,您只需将过滤器定义如下:

$scope.weDontLike = function(name) {
    return function(friend) {
        return friend.name != name;
    }
}

如您在这里看到的,weDontLike实际上返回另一个函数,该函数的范围内有您的参数以及来自过滤器的原始项。

我花了两天的时间才意识到您可以执行此操作,但尚未见过此解决方案。

检出angular.js过滤器的反极性,以了解如何将其用于过滤器的其他有用操作。


如果您的过滤器需要多个参数,请参阅如何调用具有多个参数的Angular.js过滤器?
nh2 2014年

这种方法还解决了一个奇怪的问题,即在ng-repeat内部,我无法将自己的参数传递给过滤器。不管我做了什么,他们都一直作为索引和整体收藏回来。通过执行此return方法,我能够传递我的参数并仍然加载原始元素,很好的解决!
丹尼斯·史莫里克

这个答案解决了我无法将$ scope变量作为参数传递给过滤器函数的问题。最佳解决方案。已投票!
valafar '17

如果我可以不止一次投票,那么我将确保它是SO历史上投票最多的答案。多年来,这一直困扰着我...然后我找到了(现在2岁)的答案...非常感谢。
PKD

在2019年仍然有用!非常感谢。
ashilon '19

76

据我了解,您不能将参数传递给过滤器函数(使用“过滤器”过滤器时)。您需要做的是编写一个自定义过滤器,如下所示:

.filter('weDontLike', function(){

return function(items, name){

    var arrayToReturn = [];        
    for (var i=0; i<items.length; i++){
        if (items[i].name != name) {
            arrayToReturn.push(items[i]);
        }
    }

    return arrayToReturn;
};

这是工作中的jsFiddle:http : //jsfiddle.net/pkozlowski_opensource/myr4a/1/

另一个无需编写自定义过滤器的简单替代方法是存储一个名称以在范围内过滤掉,然后编写:

$scope.weDontLike = function(item) {
  return item.name != $scope.name;
};

那就是省长,谢谢!将名称存储在范围中将无法正常工作,因为我从同一页面上的同一数据中获得了三个列表,它们使用不同的状态(或名称)进行了过滤。
shapeshifter 2012年

任何动态设置“亚当”(指的是您的JSFiddle)?在Angular中结合ngModel和自定义过滤器似乎是不可能的(我想这是故意的)
Rolf

是否可以对过滤器的参数重新排序?例如,将项目传递给过滤器的第二个参数?
Pooya 2014年

值得注意的是,在此示例中,标记为{{items | weDontLike:'thenameyoudontlike'}} ...现在,您必须去摆弄小提琴才能做到这一点。同样值得注意的是,您可以将多个参数传递给自定义过滤器{{ weDontLike:'thename':['I am','a array']:''依此类推'}},您只需向自定义过滤器添加更多参数即可访问它们。
本杰明·科南

62

实际上,您可以传递参数(http://docs.angularjs.org/api/ng.filter:filter),并且不需要为此自定义函数。如果您按照以下方式重写HTML,它将可以正常工作:

<div ng:app>
 <div ng-controller="HelloCntl">
 <ul>
    <li ng-repeat="friend in friends | filter:{name:'!Adam'}">
        <span>{{friend.name}}</span>
        <span>{{friend.phone}}</span>
    </li>
 </ul>
 </div>
</div>

http://jsfiddle.net/ZfGx4/59/


8
是。旁注-如果某人的名字是'!Adam',您会得到{name:'!! Adam'}这样的名字。
honzajde

5
您也可以像这样在此处传递数组filter:['Adam', 'john']
iConnor 2013年

6
jsfiddle链接已损坏。
Seregwethrin 2014年

4
亚当是有史以来最糟糕的名字
本·惠勒2014年

6
非非亚当显然更糟。
2014年

30

您可以在模板中简单地做到这一点

<span ng-cloak>{{amount |firstFiler:'firstArgument':'secondArgument' }}</span>

在过滤器中

angular.module("app")
.filter("firstFiler",function(){

    console.log("filter loads");
    return function(items, firstArgument,secondArgument){
        console.log("item is ",items); // it is value upon which you have to filter
        console.log("firstArgument is ",firstArgument);
        console.log("secondArgument ",secondArgument);

        return "hello";
    }
    });

这是最好的答案。它适用于动态对象。这应该是公认的答案。
abelabbesnabi


1

您可以将多个参数传递给角度滤镜!

定义我的角度应用程序和应用程序级别变量-

var app = angular.module('filterApp',[]);
app.value('test_obj', {'TEST' : 'test be check se'});

您的筛选器将类似于:-

app.filter('testFilter', [ 'test_obj', function(test_obj) {
    function test_filter_function(key, dynamic_data) {
      if(dynamic_data){
        var temp = test_obj[key]; 
        for(var property in dynamic_data){
            temp = temp.replace(property, dynamic_data[property]);
        }
        return temp;
      }
      else{
        return test_obj[key] || key;
      }

    }
    test_filter_function.$stateful = true;
    return test_filter_function;
  }]);

从HTML,您将发送如下数据:

<span ng-bind="'TEST' | testFilter: { 'be': val, 'se': value2 }"></span>

在这里,我将JSON对象发送到过滤器。您还可以发送任何类型的数据,例如字符串或数字。

您还可以将动态数量的参数传递给filter,在这种情况下,您必须使用参数来获取这些参数。

对于有效的演示,请转到此处- 将多个参数传递给角度滤镜


0

您可以简单地使用 | filter:yourFunction:arg

<div ng-repeat="group in groups | filter:weDontLike:group">...</div>

而在js中

$scope.weDontLike = function(group) {
//here your condition/criteria
return !!group 
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.