web-dev-qa-db-fra.com

Comment utiliser Regex avec ng-repeat dans AngularJs?

Je veux utiliser regex dans ng-repeat. J'ai essayé le code suivant mais cela ne fonctionne pas.

<div ng-repeat="user in users | filter:{'type':/^c5$/}"></div>

J'ai des utilisateurs tableau et je veux seulement afficher les utilisateurs avec le type c5.

Si j'utilise

filter:{'type':'c5'} 

puis affiche les utilisateurs avec le type "ac5x" aussi, car il contient c5.

Comment puis-je résoudre ce problème? Peut-être qu'il y a une autre solution.

Je vous remercie!

18
Vural Acar

Quelles mentions tosh devrait fonctionner pour vous!

Si vous souhaitez filtrer plus souvent par regex, vous pouvez créer un filtre personnalisé. Quelque chose comme ce violon vous permettra de spécifier un champ à vérifier avec une regex:

var myApp = angular.module('myApp', []);
myApp.filter('regex', function() {
  return function(input, field, regex) {
      var patt = new RegExp(regex);      
      var out = [];
      for (var i = 0; i < input.length; i++){
          if(patt.test(input[i][field]))
              out.Push(input[i]);
      }      
    return out;
  };
});

Utilisé comme ceci où 'type' indique le champ que vous vérifiez (dans ce cas, un champ nommé type):

<div ng-repeat="user in users | regex:'type':'^c5$'"></div>
36
Gloopy

Vous pouvez utiliser la fonction dans l'expression de filtre. Donc, en gros, vous pouvez effectuer tout filtrage possible avec javascript.

<li ng-repeat="name in names | filter:myFilter"> {{ name }}

Dans le contrôleur:

$scope.myFilter = function(user) {
   return /^c5$/.test(user.type);
};
16
Tosh

La réponse de Gloopy est parfaite. Je l'ai implémenté sur mon site mais je recevais une erreur,

'input' is undefined

Cela est dû au fait que je tournais parfois autour de rien. J'ai résolu ce problème en ajoutant une condition pour renvoyer le tableau vide si l'entrée n'était pas définie.

var myApp = angular.module('myApp', []);
myApp.filter('regex', function() {
  return function(input, field, regex) {
      var patt = new RegExp(regex);      
      var out = [];

      if(input === undefined) {
          return out;
      }

      for (var i = 0; i < input.length; i++){
          if(patt.test(input[i][field]))
              out.Push(input[i]);
      }      
    return out;
  };
});

Espérons que cela aidera quelqu'un qui pourrait avoir le même problème

1
Iain529

Les expressions régulières sont en effet puissantes et peuvent gérer toutes sortes de correspondances, y compris une correspondance exacte.

Cependant, étant donné que l'exemple donné dans le corps de cette question - l'expression ^c5$ - est simplement une correspondance exacte, vous pouvez spécifier que le filtre Angular exécute un correspondance exacte .

Cela traitera également du problème que vous avez avec la correspondance "ac5x".

Spécifiez true dans le troisième argument du filtre en tant que raccourci vers la fonction exact correspondance / comparateur.

Comme ceci: filter:{type:'c5'}:true

1
Colin

Merci pour l'idée du filtre regex, mais les solutions précédentes ne fonctionnent pas pour un cas général, comme un cas d'objet où se trouvent des champs à plusieurs niveaux.

Par exemple: 

<div ng-repeat="item in workers | regex:'meta.fullname.name':'^[r|R]' ">

Ma solution est:

.filter('regex', function() {
  return function(input, field, regex) {
    var f, fields, i, j, out, patt;
    if (input != null) {
      patt = new RegExp(regex);
      i = 0;
      out = [];
      while (i < input.length) {
        fields = field.split('.').reverse();
        j = input[i];
        while (fields.length > 0) {
          f = fields.pop();
          j = j[f];
        }
        if (patt.test(j)) {
          out.Push(input[i]);
        }
        i++;
      }
      return out;
    }
  };
});

Cela fonctionne pour les objets multi-niveaux ou les objets simples avec un seul niveau d'attributs.

Trop tard, mais espérons que cela vous aidera à voir sous un angle différent.

Ceci est le code dans CoffeeScript, est plus propre:

angular.module('yourApp')
    .filter 'regex', ->
        (input, field, regex) ->
            if input?
                patt = new RegExp(regex)
                i = 0
                out = []
                while i < input.length
                    fields = field.split('.').reverse()
                    j = input[i]
                    while fields.length > 0
                        f = fields.pop()
                        j = j[f]
                    if patt.test(j)
                        out.Push input[i]
                    i++
                return out
0
nahualli