web-dev-qa-db-fra.com

Qu'est-ce que "track by" dans AngularJS et comment ça marche?

Je ne comprends pas vraiment comment track by fonctionne et ce qu'il fait.
Mon objectif principal est de l'utiliser avec ng-repeat pour ajouter de la précision.

18
xoxel

En utilisant track by pour suivre les chaînes et les valeurs en double

Normalement ng-repeat suit chaque élément par l'élément lui-même. Pour le tableau donné objs = [ 'one', 'one', 2, 'five', 'string', 'foo'], ng-repeat tente de suivre les modifications par chaque obj dans le ng-repeat="obj in objs". Le problème est que nous avons des valeurs en double et angular générera une erreur. Une façon de résoudre cela est d'avoir angular suivre les objets par d'autres moyens. Pour chaînes, track by $index est une bonne solution car vous n'avez vraiment aucun autre moyen de suivre une chaîne.

track by & déclenchant un résumé et des focus d'entrée

Vous faites allusion au fait que vous êtes quelque peu nouveau pour angulaire. Un cycle de résumé se produit lorsque angular effectue une vérification exhaustive de chaque propriété surveillée afin de refléter toute modification de la vue correspondante; souvent pendant un cycle de résumé, il arrive que votre code modifie d'autres propriétés surveillées de sorte que le la procédure doit être effectuée à nouveau jusqu'à ce que angular ne détecte plus de changements.

Par exemple: vous cliquez sur un bouton pour mettre à jour un modèle via ng-click, puis vous faites quelque chose (je veux dire, les choses que vous avez écrites dans le rappel à effectuer lorsqu'un utilisateur fait un clic), puis angular déclenche le cycle de résumé afin de rafraîchir la vue. I Je ne suis pas trop explicite pour expliquer cela, alors vous devriez enquêter davantage si cela ne clarifie pas les choses.

Revenons donc à track by. Prenons un exemple:

  1. appeler un service pour renvoyer un tableau d'objets
  2. mettre à jour un objet dans le tableau et enregistrer l'objet
  3. après le service de sauvegarde, selon ce que l'API renvoie, vous pouvez:
    1. remplacer l'objet entier OU
    2. mettre à jour une valeur sur l'objet existant
  4. refléter le changement de ng-repeat UI

La façon dont vous suivez cet objet déterminera la façon dont l'interface utilisateur reflète le changement.

L'un des UX les plus ennuyeux que j'ai connu est celui-ci. Supposons que vous ayez une table d'objets, chaque cellule a une entrée où vous souhaitez modifier en ligne les propriétés de ces objets. Je souhaite modifier la valeur, puis on-blur, enregistrez cet objet tout en vous déplaçant vers la cellule suivante pour le modifier pendant que vous attendez la réponse. C'est donc une chose de type sauvegarde automatique. Selon la façon dont vous configurez votre track by, vous risquez de perdre le focus actuel (par exemple, le champ que vous modifiez actuellement) lorsque la réponse est réécrite dans votre tableau d'objets.

19
jusopi

Lorsque vous ajoutez track by vous dites essentiellement angular pour générer un seul élément DOM par objet de données dans la collection donnée.

Vous pouvez track by $index si votre source de données a des identifiants en double.

Si vous devez répéter des éléments en double, vous pouvez remplacer le comportement de suivi par défaut par le vôtre en utilisant la piste par expression.

Exemple:

[{id:1,name:'one'}, {id:1,name:'one too'}, {id:2,name:'two'}]

Essayez d'utiliser les valeurs en double dans ng-repeat, vous obtiendrez une erreur telle que:

Erreur: ngRepeat: dupes Duplicate Key in Repeater

Pour éviter ce genre de problèmes, vous devez utiliser track by $index. Par exemple:

<ul>
   <li ng-repeat="item in [1, 2, 3, 3] track by $index">
       {{ item }}
   </li>
</ul>

Voici comment vous obtiendrez $index dans imbriqué ng-repeat:

<div ng-repeat="row in matrix">
    <div ng-repeat="column in row">
      <span>outer: {{$parent.$index}} inner: {{$index}}</span>
    </div>
</div>

Voici quelques ressources qui peuvent vous aider:

12
Mohit Tanwani

Tu devrais utiliser track by uniquement si vous devez aller à l'encontre du comportement par défaut de ng-repeat qui consiste à supprimer les éléments en double.
Vous pouvez suivre les éléments à l'aide de la propriété scope $index ou en spécifiant une fonction personnalisée.

Par exemple:

<div ng-repeat="x in [42, 42, 43, 43] track by $index">
  {{x}}
</div>

Affiche toutes les valeurs du tableau (42 s'affiche deux fois).

Pour référence: https://docs.angularjs.org/api/ng/directive/ngRepeat

3
Elio Salvatore