使用angular和Animate.css按顺序制作动画

Animate in order with angular and animate.css

本文关键字:顺序 动画 css angular Animate 使用      更新时间:2023-09-26

我试图用animate css为我的角度应用程序添加一些动画。我有一个transclude=true的指令,所以我可以在父指令中插入子指令。

我写了一些自定义代码来添加动画,因为我在使用ng show时遇到了一些困难,因为我必须将不想相互依赖的模块分开,一个是表示菜单的菜单模块,另一个是安全模块,它包含一个根据用户角色显示或隐藏指令的指令。

我的角色指令看起来像这样:

(function(angular) {
'use strict';
angular.module('angSecurity')
.directive('angSecurityRole', angSecurityRole);
////////////
function angSecurityRole($timeout, PubSub) {
    var DEFAULT_ANIMATION = 'fade';
    return {
        restrict: 'A',
        transclude: false,
        multiElement: true,
        controller: 'angLoginCtrl',
        controllerAs: 'alc',
        link: function(scope, element, attr) {
            var vm = scope.alc;
            scope.$watch(function() {return attr.angSecurityRole;}, ngShowWatchAction);
            var subscriptions = [];
            //listen to role changing events
            subscriptions.push(PubSub.subscribe('event-user-logged-out' , ngShowWatchAction));
            subscriptions.push(PubSub.subscribe('event-user-logged-in'  , ngShowWatchAction));
            //remove subscriptions when destroyed
            scope.$on('$destroy', function() {
                angular.forEach(subscriptions, function(subscription) {
                    PubSub.unsubscribe(subscription);
                });
            });
            //////////////
            function ngShowWatchAction(newVal, oldVal) {
                var changed      = newVal !== oldVal;
                var actualRole   = vm.getRole();
                var requiredRole = attr.angSecurityRole;
                var show         = requiredRole === actualRole;
                var animation    = getAnimation();
                if (show) {
                    element.css('display', 'block');
                }
                element.addClass(animation);
                $timeout(function() {
                    element.removeClass(animation);
                    if (!show) {
                        element.css('display', 'none');
                    }
                }, 1000);
                ////////////////
                function getAnimation() {
                    var defaultAnimation = DEFAULT_ANIMATION + (show ? 'In' : 'Out');
                    var animation = null;
                    if (!!attr.animation && attr.animation !== null) {
                        animation = scope.$eval(attr.animation);
                        animation = show ? animation.enter : animation.leave;
                    }
                    return 'animated ' + animation ?  animation : DEFAULT_ANIMATION;               
                }
            }
        }
    };
}
})(angular);

菜单指令是:

(function(angular) {
'use strict';
angular.module('angMenu')
    .directive('angMenu', angMenu);
////////////
function angMenu() {
    return {
        transclude: true,
        templateUrl: 'app/modules/menuModule/templates/menu.tpl.html',
        controller: 'menuController',
        controllerAs: 'mc',
        scope: {},
        link: function(scope, elem, attrs) {
            var vm = scope.mc;
        }
    };
}
})(angular);

和:

(function(angular) {
'use strict';
angular.module('angMenu')
    .directive('angMenuItem', angMenuItemDirective);
////////////
function angMenuItemDirective() {
    return {
        require:    '^angMenu',
        replace:    true,
        transclude: true,
        templateUrl: 'app/modules/menuModule/templates/menuItem.tpl.html',
        scope: {
            label: '@',
            icon:  '@',
            route: '@'
        },
        link: function(scope, el, attrs, ctrl) {
            var vm = ctrl; //ctrl reffers to angMenu (parent controller)
            scope.isActive = function () {
                return el === vm.activeItem;
            };
            el.bind('click', function(ev) {
                ev.stopPropagation();
                ev.preventDefault();
                ctrl.setActiveItem(el);
                ctrl.setRoute(scope.route);
                scope.$apply();
            });
        }
    };
}
})(angular);

我希望跨接元素的动画发生在父动画之后,U怎么能做到这一点?

自定义父动画,当父动画完成时,发出事件,让孩子知道

子指令使用需要获取父控制器,并且当父控制器发出完成动画时,开始您的子动画https://docs.angularjs.org/api/ng/service/$compile#-request-

自定义您自己的动画的代码https://docs.angularjs.org/guide/animations

myModule.directive('my-directive', ['$animate', function($animate) {
  return function(scope, element, attrs) {
    element.on('click', function() {
      if(element.hasClass('clicked')) {
        $animate.removeClass(element, 'clicked');
      } else {
        $animate.addClass(element, 'clicked');
      }
    });
  };
}]);