我有一个动画,根据点击的按钮,向左或向右动画ng-repeat中的元素。
在一次操作中,我设置了一个ng-class(动画类),然后移除了触发动画的元素,但是在应用动画之前似乎没有识别出对ng-class的更改,除非我使用$scope.$apply()
,否则会引发$apply already in progress
错误。有没有办法不必使用$scope.$apply()
,或摆脱那个错误?
这是工作小提琴(有错误)。 http://jsfiddle.net/noducks/6pFr2/
HTML
<div ng-controller="MyCtrl" style="text-align: center">
<div ng-repeat="elem in elements" ng-class="elem.anim">
<button ng-click="out(elem, 'left', $index)">Left</button>
<button ng-click="out(elem, 'right', $index)">Right</button>
</div>
</div>
的Javascript
var myApp = angular.module('myApp',['ngAnimate']);
function MyCtrl($scope) {
$scope.elements = [
{anim: ''},
{anim: ''},
{anim: ''},
{anim: ''},
{anim: ''}
];
$scope.out = function(elem, direc, index) {
elem.anim = direc;
$scope.$apply();
$scope.elements.splice(index, 1);
};
}
CSS
.left.ng-leave {
-webkit-transition:all linear 1s;
transition:all linear 1s;
}
.left.ng-leave.ng-leave-active{
-ms-transform: translateX(-100%);
-o-transform: translateX(-100%);
-moz-transform: translateX(-100%);
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
.left.ng-leave {
-ms-transform: translateX(0%);
-o-transform: translateX(0%);
-moz-transform: translateX(0%);
-webkit-transform: translateX(0%);
transform: translateX(0%);
}
.right.ng-leave {
-webkit-transition:all linear 1s;
transition:all linear 1s;
}
.right.ng-leave.ng-leave-active {
-ms-transform: translateX(100%);
-o-transform: translateX(100%);
-moz-transform: translateX(100%);
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
.right.ng-leave {
-ms-transform: translateX(0%);
-o-transform: translateX(0%);
-moz-transform: translateX(0%);
-webkit-transform: translateX(0%);
transform: translateX(0%);
}
答案 0 :(得分:3)
问题是,如果从DOM中删除了重复的元素,则它们没有任何css动画信息。我猜您已经注意到,如果您删除$apply
调用,则会立即从DOM中删除这些元素。此外,您可能已经注意到,如果您对动画进行硬编码,则动画会按预期发生,例如设置class="left"
或class="right"
。
要使ngAnimation
符合您的预期$animate
服务和,浏览器需要您尝试制作动画的信息。但是,只有在DOM操作发生时,浏览器和$animate
服务才知道这些信息。
如何解决这个问题:在DOM更新css类之后,需要对$scope.elements
进行更改。所以你需要延迟一个摘要循环的DOM操作。这可以通过$timeout
服务完成(请参阅此答案以获取更多信息AngularJS : $evalAsync vs $timeout):
$scope.out = function(elem, direc, index) {
elem.anim = direc;
$timeout(function(){
$scope.elements.splice(index, 1);
});
};