108 votes

Filtrage par plusieurs propriétés spécifiques du modèle en AngularJS

Regardez l'exemple ici : http://docs.angularjs.org/api/ng.filter:filter

Vous pouvez effectuer une recherche par n'importe quelle propriété du téléphone en utilisant <input ng-model="search"> et vous pouvez effectuer une recherche par le nom uniquement en utilisant <input ng-model="search.name"> et les résultats sont correctement filtrés par nom (la saisie d'un numéro de téléphone ne renvoie aucun résultat, comme prévu).

Disons que j'ai un modèle avec une propriété "nom", une propriété "téléphone" et une propriété "secret", comment puis-je filtrer par les deux les propriétés "nom" et "téléphone" et pas la propriété "secrète" ? Donc, en substance, l'utilisateur pourrait taper un nom ou un numéro de téléphone et la fonction ng-repeat filtrerait correctement, mais même si l'utilisateur saisissait une valeur égale à une partie d'une valeur "secrète", il ne renverrait rien.

Merci.

0voto

J'aime rester simple quand c'est possible. J'avais besoin de regrouper par International, de filtrer sur toutes les colonnes, d'afficher le compte pour chaque groupe et de masquer le groupe si aucun élément n'existait.

De plus, je ne voulais pas ajouter un filtre personnalisé juste pour quelque chose de simple comme ça.

        <tbody>
            <tr ng-show="fusa.length > 0"><td colspan="8"><h3>USA ({{fusa.length}})</h3></td></tr>
            <tr ng-repeat="t in fusa = (usa = (vm.assignmentLookups | filter: {isInternational: false}) | filter: vm.searchResultText)">
                <td>{{$index + 1}}</td>
                <td ng-bind-html="vm.highlight(t.title, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.genericName, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.mechanismsOfAction, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.diseaseStateIndication, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.assignedTo, vm.searchResultText)"></td>
                <td ng-bind-html="t.lastPublished | date:'medium'"></td>
            </tr>
        </tbody>
        <tbody>
            <tr ng-show="fint.length > 0"><td colspan="8"><h3>International ({{fint.length}})</h3></td></tr>
            <tr ng-repeat="t in fint = (int = (vm.assignmentLookups | filter: {isInternational: true}) | filter: vm.searchResultText)">
                <td>{{$index + 1}}</td>
                <td ng-bind-html="vm.highlight(t.title, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.genericName, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.mechanismsOfAction, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.diseaseStateIndication, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.assignedTo, vm.searchResultText)"></td>
                <td ng-bind-html="t.lastPublished | date:'medium'"></td>
            </tr>
        </tbody>

0voto

Raj Points 91

Je suis peut-être très en retard, mais c'est ce que j'ai fini par faire. J'ai fait un filtre très général.

angular.module('app.filters').filter('fieldFilter', function() {
        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(cp[fields[i]]).toLowerCase();
                        if (haystack.indexOf(clause.query) > -1) {
                            out.push(cp);
                            break;
                        }
                    }
                })
            } else {
                angular.forEach(input, function(cp) {
                    out.push(cp);
                })
            }
            return out;
        }

    })

Ensuite, utilisez-le comme ceci

<tr ng-repeat-start="dvs in devices |  fieldFilter:search:['name','device_id']"></tr>

Votre boîte de recherche ressemble à

<input ng-model="search.query" class="form-control material-text-input" type="text">

où name et device_id sont des propriétés de dvs

-1voto

Rick Points 59

Voici une solution simple pour ceux qui veulent un filtre rapide sur un objet :

<select>
  <option ng-repeat="card in deck.Cards | filter: {Type: 'Face'}">{{card.Name}}</option>
</select>

Le filtre tableau vous permet d'imiter l'objet que vous essayez de filtrer. Dans le cas ci-dessus, les classes suivantes fonctionneraient parfaitement :

var card = function(name, type) {
  var _name = name;
  var _type = type;

  return {
    Name: _name,
    Type: _type
  };
};

Et à quoi pourrait ressembler le pont :

var deck = function() {
  var _cards = [new card('Jack', 'Face'),
                new card('7', 'Numeral')];

  return {
    Cards: _cards
  };
};

Et si vous voulez filtrer plusieurs propriétés de l'objet, il suffit de séparer les noms des champs par une virgule :

<select>
  <option ng-repeat="card in deck.Cards | filter: {Type: 'Face', Name: 'Jack'}">{{card.Name}}</option>
</select>

EDIT : Voici un plnkr fonctionnel qui fournit un exemple de filtres de propriétés simples et multiples :

http://embed.plnkr.co/i0wCx6l1WPYljk57SXzV/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X