web-dev-qa-db-fra.com

Filtre AngularJS NG-Grid - Format FilterText

J'utilise la grille AngularJS ng (v2.0.7 v2.0.8) et je voudrais comprendre la syntaxe du champ filterText dans l'API.

En particulier, je voudrais savoir comment filtrer sur une ou des colonnes spécifiques et filtrer une ou plusieurs entrées dans une colonne.

Il existe de nombreuses questions de dépassement de pile avec les balises ng-grid et filter, et bien qu'elles soient utiles, celle qui donne un résumé complet du format filterText n'est pas actuellement disponible.

25
JayInNyc

Au moment d'écrire ces lignes, il n'y a pas de résumé sur la façon de construire la chaîne 'filterText' en général. Après avoir étudié le code ng-grid.js et fait quelques suppositions, j'ai trouvé que "filterText" est beaucoup plus puissant et expressif que ne le suggère la documentation actuelle.

Exemple de configuration

Pour configurer la réponse, considérez d'abord une grille avec la définition suivante, située dans un contrôleur:

  $scope.pricing_data = data['records'];

  $scope.gridOptions = { 
    data: 'pricing_data',
    columnDefs: [
      { field: 'ticker', displayName: 'Ticker' },
      { field: 'date',   displayName: 'Date'   },
      { field: 'close',  displayName: 'Close'  },
      { field: 'volume', displayName: 'Volume' }
    ],
    filterOptions: {filterText: '', useExternalFilter: false},
    showFilter: true
  };

L'objet dans data ['records'] peut être un objet json envoyé depuis le backend. Un exemple de tableau pourrait ressembler à ceci:

an unfiltered table

En l'état, filterText est vide, donc tous les enregistrements sont présentés.

La carotte en bas à droite de la grille est visible car showFilter est vrai. Cliquez sur la carotte vers le bas pour afficher une entrée liée à la variable "filterText". Pour cette discussion, je vais montrer quelques résultats en utilisant cette liste déroulante, mais généralement vous pouvez directement attribuer à filterText dans votre code de contrôleur. La liste déroulante ressemble à ceci:

showFilter widget bound to filterText

Rechercher dans tous les champs de la grille

Par défaut, filterText exécute une expression régulière contre chaque cellule de la grille. La saisie du caractère "a" sélectionne tous les enregistrements qui ont le caractère "a" dans n'importe quelle entrée (ou colonne) de cet enregistrement. Taper "ab" sélectionne tous les enregistrements qui ont la séquence de caractères "ab" dans toute entrée de cet enregistrement. Selon vos besoins, ce comportement peut être parfaitement adapté. Cependant, avec de grands ensembles de données, on veut généralement filtrer sur les colonnes plutôt que sur la grille entière en raison de la nature des données (par exemple, sélectionner un code de prix) et en raison du coût élevé de la recherche sur la grille entière.

Recherche par colonne

Afin de rechercher une chaîne ou une expression régulière sur une seule colonne, la syntaxe filterText est:

filterText = '<displayName>:<literal>'

Par exemple,

first column filter

Ici, displayName 'Date' (n'utilisez pas la valeur du champ, vous devez utiliser displayName) est suivi par deux points ':' puis une chaîne partielle. Le résultat est que seuls trois enregistrements sont sélectionnés, ceux associés au 30 octobre.

Développons la recherche. Pour rechercher le 30 octobre ou le 31 octobre, la syntaxe est

filterText = '<displayName>:<literal 1>|<literal 2>|...'

où un tuyau '|' sépare chaque chaîne partielle. Vous pouvez enchaîner autant de fois que vous le souhaitez. Un filtre multi-date pourrait ressembler à ceci:

enter image description here

Il est clair que la sélection est de nature [~ # ~] ou [~ # ~] . Cependant, mon exemple n'est pas génial, car les tickers et les dates ont des caractères disjoints. Vous pouvez donc me faire confiance que seule la colonne Date est recherchée ou configurer votre propre exemple. (Ou, mieux encore, lisez la fonction buildSearchConditions () dans ng-grid, c'est assez clair à ce sujet).

Rechercher des entrées dans plusieurs colonnes

La recherche de plusieurs colonnes ne nécessite qu'une extension de syntaxe de la recherche dans une colonne. Cette syntaxe est:

filterText = '<displayName 1>:<lit 1>[|<lit 2>|..];<displayName 2>:<lit a>[|<lit b>|..][;..]'

L'élément lexical opératoire est le point-virgule ';' qui sépare chaque colonne displayName.

En poursuivant avec cet exemple, recherchons nyt ou nvda le 30 octobre ou le 31 octobre. Cela ressemble à:

multicolumn filter 1

Logiquement, le filtre recherche (avec Ticker nyt [~ # ~] ou [~ # ~] nvda) [~ # ~] et [~ # ~] (le long de la date pour 10-30 [~ # ~] ou [~ # ~] 10-31).

Mises à jour de la grille

Je ne connais pas trop les mises à jour qui proviennent des modifications de cellule. Je suppose que le résultat est le même.

Lorsque le contrôleur angular-js, en collaboration avec le backend, met à jour les données de la grille, puis les données mises à jour sont poussées à travers le filtre. C'est un beau résultat, en effet le filtre persiste.

Bug connu - Effacer

Au moment d'écrire ces lignes, il y avait un correctif récent à un bug connu dans lequel la suppression du filterText bloquait ou bloquait en fait le navigateur. Le rapport que j'ai suivi est celui-ci: ng-grid issue 777 . Un correctif a été fusionné après ng-grid issue 848 . Je peux certainement confirmer que je constate de mauvaises performances lorsqu'un filtre appliqué à un grand ensemble de données est effacé. Je n'ai pas encore testé le correctif.

[~ # ~] mise à jour [~ # ~]

Je viens de passer à l'installation de ng-grid 2.0.8. Le problème évident est résolu de manière définitive. Fonctionne très bien.


ng-grid 3.0

ng-grid 3.0 est maintenant sur la planche à dessin. Il y a déjà tellement de bien dans ng-grid 2.0, mais comme tout code vraiment nouveau, quelques réécritures aident. J'encourage les développeurs de ng-grid à conserver les fonctionnalités de filtrage qu'ils ont déjà incluses et peut-être à étendre les performances ou la plage.

92
JayInNyc

Sur la base de la réponse de JayInNyc, j'ai fait quelques choses pour faciliter l'utilisation par un utilisateur au lieu de suivre cette syntaxe. Je regarde essentiellement tous les champs pour lesquels je souhaite filtrer. Dans ce cas, j'ai un champ de saisie pour le nom et la ville.

$scope.filterOptions = {
    filterText: ''
};
$scope.filterName = '';
$scope.filterCity = '';

$scope.$watch('filterName', function (value) {

    setFilterText();
});

$scope.$watch('filterCity', function (value) {

    setFilterText();
});

function setFilterText()
{
    $scope.filterOptions.filterText = 'Name: ' + $scope.filterName + ';City:' + $scope.filterCity;
}

Btw - Je voulais utiliser la fonction de compilation, mais cela ne semblait pas fonctionner. J'avais ce qui suit mais cela n'a pas fonctionné.

filterOptions.filterText = $compile('Name:{{filterName}};Category:{{filterCategory}}')(scope);

9
H20rider