AngularJS过滤器 - 两个具有'或'关系的过滤器

时间:2013-10-24 17:47:45

标签: angularjs

只是想知道:在AngularJS中,是否存在一种本地方式来过滤,使其具有'或'关系而不是'和'?

例如:

<tr ng-repeat="account in accounts | filter1 *OR* filter2 *OR* filter3" >

因此,如果任何过滤器匹配,则返回该对象。截至目前,所有三个都必须通过才能显示出来。

非常感谢, ÿ

2 个答案:

答案 0 :(得分:0)

您可以编写自定义过滤器。它可以接受其他过滤器的名称并检查其中的每个过滤器以查看accounts数组中的每个项目是否与任何过滤器有效匹配。以下示例显示了这种想法,我认为我实际上并没有运行代码来查看它是否有效,所以请原谅我的任何拼写错误:

app.filter('anyOf', function($filter) {
    return function(){
        var array = arguments[0];
        var result = [];
        angular.forEach(array, function(item){
            for(var i=1; i<arguments.length; i++){
                var filter = $filter(arguments[i]);
                if(filter([item]).length){
                    result.push(item);
                    break;
                }
            }
        });
        return result;
    }
});

然后你会像这样使用它:

<tr ng-repeat="account in accounts | anyOf:'filter1':'filter2':'filter3'" >

我认为它应该可以工作,虽然它不是非常有效,因为它接受输入数组中的每个项目并检查任何过滤器。但如果您的帐户数组不长,那可能会有效。

答案 1 :(得分:0)

您可以使用$ filter在您自己的代码中调用过滤器,这样您就可以将过滤器名称作为参数传递给新过滤器以合并结果(JSFIDDLE)

app.filter('merge', function($filter) {
    return function(input, extra) {
        var result = [];
        for (var i = 1; i < arguments.length; i++) {
            angular.forEach($filter(arguments[i])(input), function(item) {
                if (result.indexOf(item) < 0) {
                    result.push(item);
                }
            });
        }
        return result;
    };
});

您可以将参数传递给过滤器,如下所示:

<ul>
    <li ng-repeat="item in items|merge:'color':'rating'">
        {{item.rating}}: {{item.color}}
    </li>
</ul>

如果你想将参数传递给你正在合并的过滤器,你可以在合并过滤器中自己解析它们:

<h3>Merge brown and rating >= 5</h3>
<ul>
    <li ng-repeat="item in items|mergeWithArgs:['color','brown']:['rating',5]">
        {{item.rating}}: {{item.color}}
    </li>
</ul>

代码:

app.filter('mergeWithArgs', function($filter) {
    return function(input) {
        console.dir(arguments);
        var result = [];
        for (var i = 1; i < arguments.length; i++) {
            var params = arguments[i];
            var filter = $filter(params[0]);
            // remove filter name, prepend input
            params.splice(0, 1, input);
            angular.forEach(filter.apply(this, params), function(item) {
                if (result.indexOf(item) < 0) {
                    result.push(item);
                }
            });
        }
        return result;
    };
});