Angular $animate 误解

Angular $animate misunderstanding

我在 AngularJS $animate 中遗漏了一些东西。我不知道我的错误是微不足道的还是巨大的误解。我试图将其缩减为最小示例,但它仍然很大。但是,至少它应该 运行 开箱即用。

<!doctype html>
<html data-ng-app="MyModule">

<head>
  <style type="text/css">
    .msg.ng-leave {
      transition: all 1s;
      opacity: 1;
    }
    
    .msg.ng-leave.ng-leave-active {
      opacity: 0;
    }
    
    .fade.ng-enter {
      transition: opacity 1s;
      opacity: 0;
    }
    
    .fade.ng-enter.ng-enter-active {
      opacity: 1;
    }
  </style>

</head>

<body data-ng-controller="MyController">
  <div class="navpanel">
    <p class="msg"><strong>This is a message, make it go away</strong></p>
    <h3>Menu</h3>
    <ul id="menulist">
      <li>Do This</li>
      <li>Do That</li>
    </ul>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
  <script>
    angular.module('MyModule', ['ngAnimate'])
      .controller('MyController', ['$scope', '$animate', function($scope, $animate) {
        let npanel = angular.element(document.querySelector('.navpanel'));
        let msg = angular.element(document.querySelector('.msg'));
        let menulist = angular.element(document.getElementById('menulist'));
        let counter = 0;
        npanel.on('click', function() {
          $animate.leave(msg);

          let newpara = angular.element(document.createElement('p'));
          newpara.html('new paragraph ' + (++counter)).addClass('fade');

          let children = npanel.children();
          $animate.enter(angular.element(newpara), npanel, menulist);
        });
      }]);
  </script>
</body>

</html>

它的目的是在点击时做两件主要的事情。一,它应该删除消息,二,它应该插入一个新段落。它执行第二个(使用 $animate.enter)但第一个完全失败(使用 $animate.leave)。

$animate.leave 似乎,从文档来看,应该 运行 通过任何动画,然后从 DOM 中删除该项目,但我的代码 none那个。相比之下,$animate.enter 没有成功执行任何动画,但是 确实 设法插入了新项目(这似乎暗示 $animate 已被正确注入)。

我错过了什么?

on 是一种 jqLite/jQuery 方法,不会触发 AngularJS' 摘要循环。这意味着当您单击元素时,附加的事件侦听器将执行,DOM 操作将被执行,但是由于摘要循环没有开始 AngularJS' 动画挂钩将不会处理动画。

您可以使用 $apply:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life cycle of exception handling, executing watches.

例如:

npanel.on('click', function() {
  $scope.$apply(function() {
    $animate.leave(msg);

    let newpara = angular.element(document.createElement('p'));
    newpara.html('new paragraph ' + (++counter)).addClass('fade');

    let children = npanel.children();
    $animate.enter(angular.element(newpara), npanel, menulist);
  });
});