0

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

例如:

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

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

非常感谢,Y

4

2 回答 2

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'" >

我认为它应该可以工作,尽管它不是很有效,因为它会获取输入数组中的每个项目并根据任何过滤器对其进行检查。但如果您的帐户数组不是超长,这可能会起作用。

于 2013-10-24T19:38:36.087 回答
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;
    };
});
于 2013-10-24T22:16:19.677 回答