Running code after an AngularJS animation has completed

前端 未结 3 934
醉梦人生
醉梦人生 2020-12-07 23:11

I have an element whose visibility is toggled by ng-show. I\'m also using CSS animations - the automatic ones from ng-animate - on this element to animate its e

相关标签:
3条回答
  • 2020-12-07 23:28

    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.

    You can see an example of this in action at this Plunker.

    0 讨论(0)
  • 2020-12-07 23:34

    @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>
    

    Plunker

    0 讨论(0)
  • 2020-12-07 23:52

    @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

    0 讨论(0)
提交回复
热议问题