AngularJS css动画+完成回调

swe*_*edo 9 javascript css animation angularjs

我正在使用AngularJS,并希望在动画完成时收到通知.我知道这可以通过像这样的javascript定义的动画来完成myApp.animation(...),但我很好奇我是否可以在没有javascript的情况下执行此操作.

问题:是否可以使用角度ng-enterng-leave css-transitions,并指定完成回调?我猜这个animationend事件被解雇了,所以应该有办法做到这一点.

我有这个:

HTML:

<div ng-if="item" class="myDiv"> {{ item.name }} </div>
Run Code Online (Sandbox Code Playgroud)

CSS:

.myDiv.ng-enter {...}
.myDiv.ng-enter.ng-enter-active {...}
.myDiv.ng-leave {...}
.myDiv.ng-leave.ng-leave-active {...}
Run Code Online (Sandbox Code Playgroud)

我想myDone()在动画结束时调用(即ng-enter-active删除类后).

Mic*_*mza 18

是的,您可以使用$animate通常在自定义指令中完成的服务.一个简单的动画案例就是在点击时以某种方式为元素设置动画.比方说,例如,使用.ng-leave指定的动画删除点击元素,传递回调

app.directive('leaveOnClick', function($animate) {
  return {
    scope: {
      'leaveOnClick': '&'
    },
    link: function (scope, element) {
      scope.leaveOnClick = scope.leaveOnClick || (function() {});
      element.on('click', function() {
        scope.$apply(function() {
          $animate.leave(element, scope.leaveOnClick);
        });
      });
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

可以使用如下:

<div class="my-div" leaveOnClick="done()">Click to remove</div>
Run Code Online (Sandbox Code Playgroud)

用CSS来淡化元素:

.my-div.ng-leave {
  opacity: 1;
  transition: opacity 1s;
  -webkit-transition: opacity 1s;
}
.my-div.ng-leave.ng-leave-active {
  opacity: 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以在此Plunker上看到上面的动画.

但是,ngIf没有任何钩子来传递回调,因为我知道,所以你必须编写自己的指令.以下是对ngIf的修改版本的描述,最初从ngIf源复制并重命名为animatedIf.它可以用于:

<div class="my-div" animated-if="shown" animated-if-leave-callback="leaveDone()" animated-if-enter-callback="enterDone()" >Some content</div>
Run Code Online (Sandbox Code Playgroud)

它的工作方式是它使用手动观察器来响应传递给它的表达式的变化animated-if.与原始ngIf的主要区别是添加了一个'scope'参数来传递回调:

scope: {
  'animatedIf': '=',
  'animatedIfEnterCallback': '&',
  'animatedIfLeaveCallback': '&'
},
Run Code Online (Sandbox Code Playgroud)

然后在动画后修改调用$animate.enter$animate.leave调用这些回调:

var callback = !oldValue && $scope.animatedIfEnterCallback ? $scope.animatedIfEnterCallback : (function() {});
$animate.enter(clone, $element.parent(), $element, callback);

$animate.leave(block.clone, ($scope.animatedIfLeaveCallback || (function() {})));
Run Code Online (Sandbox Code Playgroud)

在初始加载指令时不调用回调有点复杂.由于该scope参数,该指令创建了一个隔离的范围,然后在转换内容时使用该范围.因此,需要进行的另一项更改是从$parent指令范围创建并使用作为子项的作用域:行

 childScope = $scope.$new();
Run Code Online (Sandbox Code Playgroud)

必须改为

 childScope = $scope.$parent.$new();
Run Code Online (Sandbox Code Playgroud)

您可以在此Plunker中查看修改后的ngIf指令的完整来源.这只是非常短暂的测试.

可能有一种更简单的方法,可能是不完全重新创建ngIf指令,而是创建一个带有模板的指令,该模板使用带有一些包装div的原始ngIf,例如

template: '<div><div ng-if="localVariable"><div ng-transclude></div></div></div>'
Run Code Online (Sandbox Code Playgroud)