角。具有多个值(或值)之一的属性的js ng-repeat过滤器

时间:2022-08-23 23:36:55

Is it possible to filter an array of objects, such that the value of property can be either of a few values (OR condition) without writing a custom filter

是否可以过滤一个对象数组,这样属性的值可以是几个值(或条件),而不需要编写自定义过滤器?

This is similar to this problem - Angular.js ng-repeat :filter by single field

这和这个问题很相似,角的。js ng-repeat:单字段过滤

But instead of

但相反的

<div ng-repeat="product in products | filter: { color: 'red' }">

is it possible to do something like this

有可能做这样的事吗

<div ng-repeat="product in products | filter: { color: 'red'||'blue' }">

for a sample data as follows-

对于以下示例数据

$scope.products = [
   { id: 1, name: 'test', color: 'red' },
   { id: 2, name: 'bob', color: 'blue' }
   /*... etc... */
];

I've unsuccessfully tried

我失败的尝试

<div ng-repeat="product in products | filter: { color: ('red'||'blue') }">

7 个解决方案

#1


78  

Best way to do this is to use a function:

最好的方法是使用一个函数:

<div ng-repeat="product in products | filter: myFilter">

$scope.myFilter = function (item) { 
    return item === 'red' || item === 'blue'; 
};

Alternatively, you can use ngHide or ngShow to dynamically show and hide elements based on a certain criteria.

或者,您可以使用ngHide或ngShow根据特定的条件动态显示和隐藏元素。

#2


23  

For me, it worked as given below..

对我来说,它的效果如下所示。

<div ng-repeat="product in products | filter: { color: 'red'} | filter: { color:'blue' }">

#3


11  

I thing "ng-if" should work:

我认为“ng-if”应该有效:

<div ng-repeat="product in products" ng-if="product.color === 'red' 
|| product.color === 'blue'">

#4


9  

In HTML:

在HTML中:

<div ng-repeat="product in products | filter: colorFilter">

In Angular:

角:

$scope.colorFilter = function (item) { 
  if (item.color === 'red' || item.color === 'blue') {
  return item;
 }
};

#5


5  

Here is a way to do it while passing in an extra argument:

这里有一种方法,在传递一个额外的参数:

https://*.com/a/17813797/4533488 (thanks to Denis Pshenov)

https://*.com/a/17813797/4533488(感谢Denis Pshenov)

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

With the backend:

后端:

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

.


And yet another way with an in-template filter only:

另一种使用模板过滤器的方法是:

https://*.com/a/12528093/4533488 (thanks to mikel)

https://*.com/a/12528093/4533488(由于米克尔)

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

#6


2  

I found a more generic solution with the most angular-native solution I can think. Basically you can pass your own comparator to the default filterFilter function. Here's plunker as well.

我找到了一种更通用的解决方案,我能想到的最优解。基本上,您可以将自己的比较器传递给默认的过滤函数。这是一美元。

#7


0  

After not able to find a good universal solution I made something of my own. I have not tested it for a very large list.

在没有找到一个好的通用解决方案后,我自己做了一些事情。我还没有为一个非常大的列表测试它。

It takes care of nested keys,arrays or just about anything.

它负责嵌套的键、数组或任何东西。

Here is the github and demo

这是github和demo

app.filter('xf', function() {
    function keyfind(f, obj) {
        if (obj === undefined)
            return -1;
        else {
            var sf = f.split(".");
            if (sf.length <= 1) {
                return obj[sf[0]];
            } else {
                var newobj = obj[sf[0]];
                sf.splice(0, 1);
                return keyfind(sf.join("."), newobj)
            }
        }

    }
    return function(input, clause, fields) {
        var out = [];
        if (clause && clause.query && clause.query.length > 0) {
            clause.query = String(clause.query).toLowerCase();
            angular.forEach(input, function(cp) {
                for (var i = 0; i < fields.length; i++) {
                    var haystack = String(keyfind(fields[i], cp)).toLowerCase();
                    if (haystack.indexOf(clause.query) > -1) {
                        out.push(cp);
                        break;
                    }
                }
            })
        } else {
            angular.forEach(input, function(cp) {
                out.push(cp);
            })
        }
        return out;
    }

})

HTML

HTML

<input ng-model="search.query" type="text" placeholder="search by any property">
<div ng-repeat="product in products |  xf:search:['color','name']">
...
</div>

#1


78  

Best way to do this is to use a function:

最好的方法是使用一个函数:

<div ng-repeat="product in products | filter: myFilter">

$scope.myFilter = function (item) { 
    return item === 'red' || item === 'blue'; 
};

Alternatively, you can use ngHide or ngShow to dynamically show and hide elements based on a certain criteria.

或者,您可以使用ngHide或ngShow根据特定的条件动态显示和隐藏元素。

#2


23  

For me, it worked as given below..

对我来说,它的效果如下所示。

<div ng-repeat="product in products | filter: { color: 'red'} | filter: { color:'blue' }">

#3


11  

I thing "ng-if" should work:

我认为“ng-if”应该有效:

<div ng-repeat="product in products" ng-if="product.color === 'red' 
|| product.color === 'blue'">

#4


9  

In HTML:

在HTML中:

<div ng-repeat="product in products | filter: colorFilter">

In Angular:

角:

$scope.colorFilter = function (item) { 
  if (item.color === 'red' || item.color === 'blue') {
  return item;
 }
};

#5


5  

Here is a way to do it while passing in an extra argument:

这里有一种方法,在传递一个额外的参数:

https://*.com/a/17813797/4533488 (thanks to Denis Pshenov)

https://*.com/a/17813797/4533488(感谢Denis Pshenov)

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

With the backend:

后端:

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

.


And yet another way with an in-template filter only:

另一种使用模板过滤器的方法是:

https://*.com/a/12528093/4533488 (thanks to mikel)

https://*.com/a/12528093/4533488(由于米克尔)

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

#6


2  

I found a more generic solution with the most angular-native solution I can think. Basically you can pass your own comparator to the default filterFilter function. Here's plunker as well.

我找到了一种更通用的解决方案,我能想到的最优解。基本上,您可以将自己的比较器传递给默认的过滤函数。这是一美元。

#7


0  

After not able to find a good universal solution I made something of my own. I have not tested it for a very large list.

在没有找到一个好的通用解决方案后,我自己做了一些事情。我还没有为一个非常大的列表测试它。

It takes care of nested keys,arrays or just about anything.

它负责嵌套的键、数组或任何东西。

Here is the github and demo

这是github和demo

app.filter('xf', function() {
    function keyfind(f, obj) {
        if (obj === undefined)
            return -1;
        else {
            var sf = f.split(".");
            if (sf.length <= 1) {
                return obj[sf[0]];
            } else {
                var newobj = obj[sf[0]];
                sf.splice(0, 1);
                return keyfind(sf.join("."), newobj)
            }
        }

    }
    return function(input, clause, fields) {
        var out = [];
        if (clause && clause.query && clause.query.length > 0) {
            clause.query = String(clause.query).toLowerCase();
            angular.forEach(input, function(cp) {
                for (var i = 0; i < fields.length; i++) {
                    var haystack = String(keyfind(fields[i], cp)).toLowerCase();
                    if (haystack.indexOf(clause.query) > -1) {
                        out.push(cp);
                        break;
                    }
                }
            })
        } else {
            angular.forEach(input, function(cp) {
                out.push(cp);
            })
        }
        return out;
    }

})

HTML

HTML

<input ng-model="search.query" type="text" placeholder="search by any property">
<div ng-repeat="product in products |  xf:search:['color','name']">
...
</div>