web-dev-qa-db-fra.com

Qu'est-ce que le filtrage avec état dans AngularJS?

Je lisais le guide du développeur AngularJS dans la section Filtre ( https://docs.angularjs.org/guide/filter#stateful-filters ) et je suis tombé sur "Stateful Filters".

Cette description est donnée comme suit:

Il est fortement déconseillé d'écrire des filtres avec état, car leur exécution ne peut pas être optimisée par Angular, ce qui entraîne souvent des problèmes de performances. De nombreux filtres avec état peuvent être convertis en filtres sans état simplement en exposant l'état caché en tant que modèle et en le transformant en argument pour le filtre.

Je suis nouveau dans le développement Web, donc je n'ai aucune idée de ce qu'est le filtrage avec état, et Angular ne l'a pas expliqué non plus :( Quelqu'un peut-il expliquer la différence entre un filtre normal et un filtre avec état est?

43
alamoot

"État" fait référence aux variables/propriétés/etc qui sont définies dans l'application. Ces valeurs peuvent changer à tout moment. Les documents disent que le filtre ne devrait pas dépendre d'un "état" externe. Tout ce que le filtre doit savoir doit être transmis comme argument lors du filtrage, et le filtre doit alors avoir tout ce dont il a besoin pour effectuer le filtrage et renvoyer le résultat. Regardez la démo dans les documents et vous verrez que dans le " avec état ", le filtre a une dépendance sur un service qu'il utilise pour effectuer le filtrage. Cette valeur de service peut changer pendant un cycle $digest, Donc la propriété $stateful Doit être définie sur le filtre pour que Angular exécutera à nouveau le filtre pour être sûr que la dépendance n'a pas changé d'état, ce qui change le résultat du filtre.

Ainsi, tous les "états" devraient être dans les arguments, comme ceci:

<p>{{myData | multiplyBy:multiplier}}</p>

Avec un filtre comme:

.filter('multiplyBy', function() {
  function filter(input, multiplier) {
    return input * multiplier;
  }
  return filter;
})

Si les données ou les arguments changent, le filtre s'exécutera à nouveau.

La version stateful serait quelque chose comme ça (non recommandé!):

<p>{{myData | myFilter}}</p>

Et le filtre obtient les informations dont il a besoin à partir de sources externes:

.filter('myFilter', ['someDependency', function(someDependency) {
  function filter(input) {
    // let's just say `someDependency = {multiplier: 3}`
    return input * someDependency.multiplier;
  }
  filter.$stateful = true;
  return filter;
}])

Dans cet exemple de filtre, someDependency.multiplier Aurait dû être passé en argument au filtre (comme dans le premier exemple), plutôt que d'être une dépendance du filtre.

Pour clarifier davantage le problème: Si vous avez appelé une fonction comme celle-ci: foo(20) et obtenez un résultat de 40, Vous devriez obtenir le même résultat si vous répétez le processus. Si vous appeliez à nouveau foo(20) et obteniez 92, Ce serait plutôt déroutant, non? En supposant que foo n'est pas une fonction conçue pour renvoyer des valeurs aléatoires, la seule façon dont elle pourrait renvoyer des nombres différents à chaque fois est si elle fonctionne différemment en fonction d'un état caché (quelque chose changeant en interne, plutôt que d'être transmis dans comme argument). L'idée que la fonction retournerait la même à chaque fois avec les mêmes arguments est appelée "idempotente".

Remarque: $stateful Semble être nouveau dans Angular 1.

69
m59