Angular.js ng-repeat filter por propiedad que tiene uno de múltiples valores (O de valores)

4 minutos de lectura

Avatar de usuario de Yogesh Mangaj
Yogesh Mangaj

¿Es posible filtrar una matriz de objetos, de modo que el valor de la propiedad pueda ser de algunos valores (O condición)? sin escribir un filtro personalizado

Esto es similar a este problema: Angular.js ng-repeat: filtrar por campo único

pero en lugar de

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

es posible hacer algo como esto

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

para una muestra de datos de la siguiente manera-

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

he intentado sin exito

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

  • Podría ayudarte stackoverflow.com/questions/15868248/…

    – Satpal

    24 de febrero de 2014 a las 12:35

  • consulte mi respuesta – stackoverflow.com/questions/27606595/…

    – Ravindra Vairagui

    16 de septiembre de 2016 a las 5:07

  • ¿Responde esto a tu pregunta? Cómo filtrar valores múltiples (operación OR) en angularJS

    – Vega

    6 de agosto de 2020 a las 4:33

Avatar de usuario de Sherlock
sherlock

La mejor manera de hacer esto es usar una función:

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

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

Como alternativa, puede utilizar ngOcultar o ngMostrar para mostrar y ocultar dinámicamente elementos en función de ciertos criterios.

  • Además de una función o un filtro personalizado, ¿no hay forma de hacerlo en línea? ngHide establecerá el display a nonepero el div se generará e insertará en el DOM. De todos modos, creo que la función es la forma más limpia de hacerlo, solo tenía curiosidad si había una sintaxis para especificar una condición OR en línea.

    – Yogesh Mangaj

    24/02/2014 a las 13:00


  • @Sherlock Para ser más precisos, debe agregar el atributo de color: $scope.myFilter = function (item) { return item.color === 'red' || item.color === 'blue'; };

    – jDelforge

    5 de septiembre de 2019 a las 2:43


Avatar de usuario de Amol Aranke
Amol Aranke

Para mí, funcionó como se indica a continuación:

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

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

  • ¿No sería esto más como una condición “y”?

    – Shikyō

    10 oct 2017 a las 17:16

avatar de usuario de jrock10
jrock10

yo pienso ng-if Deberia trabajar:

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

  • Esto funciona, pero $index se referirá al índice de matriz original

    – ematias

    25 de enero de 2018 a las 10:19

En HTML:

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

En Angular:

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

avatar de usuario de aero
aerodinámico

Aquí hay una manera de hacerlo mientras se pasa un argumento adicional:

https://stackoverflow.com/a/17813797/4533488 (gracias a 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>

Con el back-end:

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

.


Y otra forma más con un filtro en la plantilla únicamente:

https://stackoverflow.com/a/12528093/4533488 (gracias a mikel)

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

Avatar de usuario de la comunidad
Comunidad

Encontré una solución más genérica con la solución nativa más angular que puedo pensar. Básicamente puedes pasar tu propio comparador al predeterminado filterFilter función. Aquí está golpeador también.

Avatar de usuario de Raj Nandan Sharma
Raj Nandan Sharma

Después de no poder encontrar una buena solución universal, hice algo propio. No lo he probado para una lista muy grande.

Se ocupa de claves anidadas, matrices o casi cualquier cosa.

Aquí está el github y manifestación

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

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

¿Ha sido útil esta solución?