Angular ng-repeat provoque un scintillement

Je présente une liste de vignettes avec ce code:

<div class ="channel" ng-repeat ="channel in UIModel.channels" ng-class ="{evenchannel: ($index % 2) == 0, oddchannel: ($index % 2) == 1}"> <img class="channel-img" ng-src ="data/channels/{{$index + 1}}/thumb"/> </div> 

Dans le contrôleur, j'ai une requête ajax qui prend de nouvelles images miniatures. Angular met ainsi à jour les images mais provoque un scintillement. Existe-t-il un moyen de double tampon ou la liste n'a-t-elle pas été supprimée lors de la mise à jour du DOM?

Pour suivre la réponse de @ cexbrayat, si vous n'avez pas d'identifiant, vous pouvez également l'associer et track by $index . Quelle est une itération interne # lors d'une répétition ng.

 <div ng-repeat="channel in UIModel.channels track by $index"></div> 

Vous pouvez utiliser la track by dans votre ng-repeat avec un identifiant unique. Si je suppose que votre objet de canal a un identifiant, vous pouvez:

 <div class ="channel" ng-repeat="channel in UIModel.channels track by channel.id"></div> 

Le suivi évite la suppression complète des DOM et les loisirs à chaque mise à jour, car Angular pourra suivre si l'élément est identique à celui précédemment et conserver l'élément DOM.

Essayez les réponses de @Mark Pieszak et @cexbrayat d'abord, mais si vous utilisez ngAnimate dans votre application, ils peuvent ne pas résoudre complètement votre problème.

En plus de:

 <div class="channel" ng-repeat="channel in UIModel.channels track by channel.id"></div> 

J'avais besoin d'ajouter le CSS suivant pour désactiver l'animation pour cette ng-repeat :

 .channel .ng-leave, .channel .ng-leave-active { display: none !important; } .channel .ng-move, .channel .ng-move-active { display: none !important; } 

Cela garantit qu'une fois l'animation démarrée, l'élément est immédiatement caché. Les alternatives sont d'utiliser une animation, ou de désactiver l'animation sur l'élément dans le code avec $animate.enabled('div.channel', false); .

J'avais le même problème, l'utilisation de la piste par $ index m'a finalement résolu le problème. Au début, je ne pensais pas le faire, car je l'utilisais directement dans les balises d'image où était une autre répétition ng. Une fois que je l'ai mis dans la division parent (ainsi) sur ng-repeat it worked:

 <div ng-repeat="item in blah track by $index"> <!-- stuff --> <!-- later in this div: --> <img data-ng-repeat="dict in item.blah track by $index" class="smallPics ng-cloak" src="{[dict.path]}"></img> <!-- and the rest is blah-istory --> 

Comme note:

Si l'utilisation de la track by $index ne met pas à jour le DOM avec les nouvelles valeurs,
ngDupe utiliser une track by 'the properties you expect to change' ngDupe attention à éviter les erreurs ngDupe

par exemple:

 <div ng-repeat="channel in UIModel.channels track by customExp(channel)"> 

. . .

 $scope.customExp = function(chan) { return chan.id+chan.thumbnail_url; // this has to ensure uniqueness } 

ou

 <div ng-repeat="channel in UIModel.channels track by channel.id+channel.thubnail_url">