2014-02-09 13 views
4

我有一個動畫,根據點擊哪個按鈕,將ng-repeat中的元素向左或右移動。

在一次操作中,我設置了一個ng-class(動畫類),然後刪除觸發動畫的元素,但在應用動畫之前似乎沒有認識到對ng類的改變,除非我使用$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%); 
} 

回答

3

的概率lem是你的重複元素如果從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); 
    }); 
}; 
+0

感謝邁克爾。我曾希望不必使用超時。話雖如此,我試圖整合您的解決方案,但這些元素似乎不再具有動畫效果。 http://jsfiddle.net/noducks/a9JEn/有什麼想法? –

+0

@noducks你需要在你的控制器中包含$ timeout:function MyCtrl($ scope,$ timeout) – michael