Angular.js: ng-if se comporte bizarrement avec les animations d'images clés infinies CSS

Créé le 3 janv. 2014  ·  3Commentaires  ·  Source: angular/angular.js

Lié à https://github.com/angular/angular.js/issues/4818

Voir le Plunker suivant : http://plnkr.co/edit/i1DJ6ejtuHVFHty9jxfe?p=preview

L'élément <div class="box" ng-if="showBox"> a une animation infinie de 5 secondes pour un fond de cycle permanent. Lorsque la valeur de showBox est basculée, l'animation de l'élément recommence et il n'est pas supprimé du DOM tant que les 5 secondes entières ne se sont pas écoulées - bien qu'aucune animation entrée/sortie ne soit définie.

Encore plus problématique : si vous basculez la valeur plusieurs fois avant la fin de l'animation (cliquez plusieurs fois sur la case à cocher), plusieurs copies de l'élément sont affichées simultanément.

ngAnimate moderate bug

Commentaire le plus utile

Le problème est que ngAnimate pense que votre animation infinie est là pour tous les événements d'animation utilisés (comme entrer, partir, etc.). Et comme il s'agit d'une animation infinie, les événements CSS ne sont jamais déclenchés tant que le compte à rebours final n'est pas écoulé, ce qui est après 7,5 secondes (5 x 1,5 == 7,5).

Vous devrez dire à ng-animate de ne pas animer l'animation d'arrière-plan infinie en remplaçant la classe CSS .ng-animate sur l'élément et en annulant les animations d'images clés.

http://plnkr.co/edit/fq7ZEO7tDnqLmavHoBfQ?p=preview

.box.ng-animate {
  -webkit-animation: none 0s;
  animation: none 0s;
}

Malheureusement, la détection des styles et des classes CSS en JavaScript est très limitée. Avec les versions antérieures d'AngularJS, nous avions la règle selon laquelle vous ne pouvez définir l'animation/la transition CSS que sur la propriété d'animation (comme .ng-enter, .ng-leave, etc.), mais cela a causé plus de problèmes qu'il n'en a résolu. Donc, dans ce cas, vous devez faire l'inverse.

PS. Tout ce dont vous avez besoin est le préfixe -webkit- et les propriétés standard animation puisque tous les autres fournisseurs ont abandonné leurs préfixes.

Tous les 3 commentaires

Le problème est que ngAnimate pense que votre animation infinie est là pour tous les événements d'animation utilisés (comme entrer, partir, etc.). Et comme il s'agit d'une animation infinie, les événements CSS ne sont jamais déclenchés tant que le compte à rebours final n'est pas écoulé, ce qui est après 7,5 secondes (5 x 1,5 == 7,5).

Vous devrez dire à ng-animate de ne pas animer l'animation d'arrière-plan infinie en remplaçant la classe CSS .ng-animate sur l'élément et en annulant les animations d'images clés.

http://plnkr.co/edit/fq7ZEO7tDnqLmavHoBfQ?p=preview

.box.ng-animate {
  -webkit-animation: none 0s;
  animation: none 0s;
}

Malheureusement, la détection des styles et des classes CSS en JavaScript est très limitée. Avec les versions antérieures d'AngularJS, nous avions la règle selon laquelle vous ne pouvez définir l'animation/la transition CSS que sur la propriété d'animation (comme .ng-enter, .ng-leave, etc.), mais cela a causé plus de problèmes qu'il n'en a résolu. Donc, dans ce cas, vous devez faire l'inverse.

PS. Tout ce dont vous avez besoin est le préfixe -webkit- et les propriétés standard animation puisque tous les autres fournisseurs ont abandonné leurs préfixes.

Cool, merci pour la solution de contournement.

Le truc des copies multiples à la fois me semble toujours être un bogue : j'écris mon code en supposant qu'un élément utilisant ng-if est présent une fois ou pas du tout, et je m'attendrais à ce que framework pour l'empêcher de se briser si facilement en raison d'une erreur noob par inadvertance. Veuillez me corriger si j'ai mal compris comment ng-if (ou ng-switch ) est censé fonctionner.

Les copies multiples étaient là parce que les animations étaient toujours en cours. Et $animate a une animation catch-all pour les images clés/transitions qui se produisent après l'expiration de votre durée * 1.5. C'est pourquoi ils disparaissent au bout d'un moment.

Votre code ng-if est correct. Et oui, c'est seulement là quand c'est vrai. Mais les internes font une nouvelle copie de l'élément chaque fois que l'expression redevient vraie. Mais comme l'animation est suspendue à l'élément plus ancien, elle n'a pas encore été supprimée jusqu'à ce que l'animation catch all arrive.

Et ng-switch et ng-if fonctionnent de la même manière. Seul ng-switch a plusieurs éléments au lieu d'un seul.

Cette page vous a été utile?
0 / 5 - 0 notes