$animate.enter() 不适用于自定义指令

$animate.enter() is not working with custom directive

在使用 angular-animate 1.4.3 时遇到问题...指令的离开动画效果很好,但进入动画效果不佳;据我所见,类 ng-enterng-enter-active 未应用于元素。为什么是这样? Here's a plunkr of it

script.js

(function() {
  'use strict';

  // ---------------Module----------------

  angular.module('app', ['ngAnimate'])
    .run(['fooService', function(fooService) {
      fooService.foo('Hello World!');
    }]);

  // --------------Service----------------

  function fooService($rootScope, $compile, $animate, $timeout) {

    function createDirective(message) {
      var newFoo = {
        scope: $rootScope.$new()
      };

      var target = angular.element(document.querySelector('#bar'));
      var elem = angular.element(document.createElement('foo'));

      newFoo.scope.message = message;

      newFoo.elem = $compile(elem)(newFoo.scope);

      $animate.enter(newFoo.elem, target).then(function() {
        $timeout(function() {
          removeDirective(newFoo);
        }, 3000);
      });
    }

    function removeDirective(foo) {
      $animate.leave(foo.elem).then(function() {
        foo.scope.$destroy();
      });
    }


    function foo(message, overrides) {
      return createDirective(message);
    }

    return {
      foo: foo
    };
  }

  fooService.$inject = ['$rootScope', '$compile', '$animate', '$timeout'];

  angular.module('app')
    .factory('fooService', fooService);

  // -------------Directive---------------

  function fooDirective() {
    return {
      restrict: 'AE',
      replace: true,
      templateUrl: 'foo.html',
      link: function(scope) {
      }
    }
  }

  angular.module('app')
    .directive('foo', fooDirective);

}());

foo.html

<div class="alert alert-success">
  {{message}}
</div>

index.html

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <link data-require="bootstrap-css@3.3.1" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script data-require="angular.js@~1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
    <script data-require="angular-animate@1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular-animate.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div id="bar"></div>
  </body>

</html>

style.css

.ng-leave, .ng-enter {
  transition: all 1s ease-out;
}

.ng-enter.ng-enter-active, .ng-leave {
  opacity: 1;
}

.ng-enter, .ng-leave.ng-leave-active {
  opacity: 0;
}

感谢任何帮助

Angular 没有 link 编译指令。你可以阅读一些关于这个 here.

此案例的影响导致 linking after $animate.enter()。您可以将此调用包装到超时中,但这不是一个可持续的解决方案,因为这个时间取决于浏览器的繁忙程度以及它是否是第一次为该应用程序 linked 指令。所以我只看到一种基于承诺的方法。由于自定义指令已经存在范围注入,后者可以解决 fooService

提供的承诺
  newFoo.scope.deferred = $q.defer();
  newFoo.scope.deferred.promise.then(function(){
    console.log('$animate.enter');
    $animate.enter(newFoo.elem, target).then(function() {
      console.log('$animate.entered');
      $timeout(function() {
        removeDirective(newFoo);
      }, 3000);
    });
  });

并且在指令中承诺应在 link

上解决
  link: function(scope) {
    console.log('foo.link');
    scope.deferred.resolve();
  }

Updated Plunker