Running code after an AngularJS animation has completed
As @zeroflagL has suggested, a custom directive to replace ngShow
is probably the way to go. You can use &
to pass callbacks into the directive, which can be called after the animations have finished. For consistency, the animations are done by adding and removing the ng-hide
class, which is the same method used by the usual ngShow directive:
app.directive('myShow', function($animate) { return { scope: { 'myShow': '=', 'afterShow': '&', 'afterHide': '&' }, link: function(scope, element) { scope.$watch('myShow', function(show, oldShow) { if (show) { $animate.removeClass(element, 'ng-hide', scope.afterShow); } if (!show) { $animate.addClass(element, 'ng-hide', scope.afterHide); } }); } }})
Example use of this listening to a scope variable show
would be:
<div my-show="show" after-hide="afterHide()" after-show="afterShow()">...</div>
Because this is adding/removing the ng-hide class, the points about animating from the docs about ngShow are still valid, and you need to add display: block !important
to the CSS.
@michael-charemza answer worked great for me. If you are using Angular 1.3 they changed the promise a little. I got stuck on this for a little bit but here is the change that got it to work:
if (show) { $animate.removeClass(element, 'ng-hide').then(scope.afterShow);}if (!show) { $animate.addClass(element, 'ng-hide').then(scope.afterHide);}
Plunker: Code Example
@michal-charemza solution works great, but the directive creates an isolated scope, so in some cases it cannot be a direct replacement for the default ng-show directive.
I have modified it a bit, so that it does not create any new scopes and can be used interchangeably with the ng-show directive.
app.directive('myShow', function($animate) { return { link: function(scope, element, attrs) { scope.$watch(attrs['myShow'], function(show, oldShow) { if (show) { $animate.removeClass(element, 'ng-hide').then(function(){ scope.$apply(attrs['myAfterShow']); }); } else { $animate.addClass(element, 'ng-hide').then(function(){ scope.$apply(attrs['myAfterHide']); }); } }); } }})
Usage:
<div my-show="show" my-after-hide="afterHide()" my-after-show="afterShow()">...</div>