Relacionado a https://github.com/angular/angular.js/issues/4818
Veja o seguinte Plunker: http://plnkr.co/edit/i1DJ6ejtuHVFHty9jxfe?p=preview
O elemento <div class="box" ng-if="showBox">
tem uma animação infinita de 5 segundos para um fundo em ciclo permanente. Quando o valor de showBox
é alternado, a animação do elemento começa novamente e não é removida do DOM até que os 5 segundos inteiros tenham se passado - apesar de nenhuma animação entrar / sair sendo definida.
Ainda mais problemático: se você alternar o valor várias vezes antes de a animação terminar (clique na caixa de seleção várias vezes), várias cópias do elemento serão exibidas simultaneamente.
O problema é que o ngAnimate pensa que sua animação infinita está lá para todos os eventos de animação usados (como entrar, sair e assim por diante). E como é uma animação infinita, os eventos CSS nunca são disparados até que a contagem regressiva final tenha passado, que é após 7,5 segundos (5 x 1,5 == 7,5).
Você precisará dizer ao ng-animate para não animar a animação de fundo infinito, substituindo a classe CSS .ng-animate
no elemento e cancelando as animações de quadro-chave.
http://plnkr.co/edit/fq7ZEO7tDnqLmavHoBfQ?p=preview
.box.ng-animate {
-webkit-animation: none 0s;
animation: none 0s;
}
Infelizmente, a detecção de estilos e classes CSS em JavaScript é altamente limitada. Com as versões anteriores do AngularJS, tínhamos a regra de que você só pode definir a animação / transição CSS na propriedade da animação (como .ng-enter, .ng-leave e assim por diante), mas isso causou mais problemas do que resolveu. Portanto, neste caso, você precisa fazer o oposto.
PS. Tudo que você precisa é o prefixo -webkit-
e as propriedades animation
padrão, já que todos os outros fornecedores abandonaram seus prefixos.
Legal, obrigado pela solução alternativa.
A coisa de múltiplas cópias de uma só vez ainda parece um bug para mim: eu escrevo meu código pressupondo que um elemento usando ng-if
está presente uma vez ou não está presente, e espero que o estrutura para evitar que se quebre tão facilmente devido a um erro inadvertido noob. Por favor, corrija-me se eu não entendi como ng-if
(ou ng-switch
) deve funcionar.
As cópias múltiplas estavam lá porque as animações ainda estavam acontecendo. E $ animate tem uma animação catch-all
para quadros-chave / transições que ocorre depois que sua duração * 1.5 expira. É por isso que eles desaparecem após um momento.
Seu código ng-if está correto. E sim, só existe quando é verdade. Mas os internos fazem uma nova cópia do elemento cada vez que a expressão se torna verdadeira novamente. Mas, como a animação está pendurada no elemento mais antigo, ela ainda não foi excluída até que todas as animações cheguem.
E ng-switch e ng-if operam da mesma maneira. Apenas o ng-switch possui vários elementos em vez de apenas um.
Comentários muito úteis
O problema é que o ngAnimate pensa que sua animação infinita está lá para todos os eventos de animação usados (como entrar, sair e assim por diante). E como é uma animação infinita, os eventos CSS nunca são disparados até que a contagem regressiva final tenha passado, que é após 7,5 segundos (5 x 1,5 == 7,5).
Você precisará dizer ao ng-animate para não animar a animação de fundo infinito, substituindo a classe CSS
.ng-animate
no elemento e cancelando as animações de quadro-chave.http://plnkr.co/edit/fq7ZEO7tDnqLmavHoBfQ?p=preview
Infelizmente, a detecção de estilos e classes CSS em JavaScript é altamente limitada. Com as versões anteriores do AngularJS, tínhamos a regra de que você só pode definir a animação / transição CSS na propriedade da animação (como .ng-enter, .ng-leave e assim por diante), mas isso causou mais problemas do que resolveu. Portanto, neste caso, você precisa fazer o oposto.
PS. Tudo que você precisa é o prefixo
-webkit-
e as propriedadesanimation
padrão, já que todos os outros fornecedores abandonaram seus prefixos.