【问题标题】:Running code after an AngularJS animation has completed在 AngularJS 动画完成后运行代码
【发布时间】:2014-01-22 04:24:40
【问题描述】:

我有一个元素的可见性由ng-show 切换。我还在此元素上使用 CSS 动画(ng-animate 中的自动动画)来为其条目设置动画。

该元素将包含图像或视频。

如果元素包含视频,我想播放它,但我不想播放视频,直到它完成动画。

因此,我想知道是否有一种简单的方法可以将回调绑定到 AngularJS 中 CSS 动画的末尾?

docs 引用了 doneCallback,但我看不到指定它的方法...

我想到的一种解决方法(?)是$watching element.hasClass("ng-hide-add-active") 并等待它与(true, false) 一起触发,这意味着它刚刚被删除..

有更好的方法吗?

【问题讨论】:

  • 你在css动画中指定秒数,在$timeout中设置相同的秒数?
  • @YOU :我可以这样做,但在我看来这更不整洁 - 两者完全相互分离。
  • 顺便说一句,关于 css 动画回调有一些问题 - stackoverflow.com/q/6186454stackoverflow.com/q/9255279stackoverflow.com/q/2087510
  • 谢谢,但这个问题更多是关于 angularjs,而不是通用 css 动画。
  • 您使用自己的指令代替 ng-show。或者,如果您已经有一个,那么也将它用于您的动画并删除 ng-show。

标签: angularjs css-animations ng-animate


【解决方案1】:

@michal-charemza 解决方案效果很好,但是该指令创建了一个隔离范围,因此在某些情况下它不能直接替代默认的 ng-show 指令。

我对其进行了一些修改,使其不会创建任何新的范围,并且可以与 ng-show 指令互换使用。

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']);
          });
        }
      });
    }
  }
})

用法:

<div my-show="show" my-after-hide="afterHide()" my-after-show="afterShow()">...</div>

Plunker

【讨论】:

    【解决方案2】:

    @michael-charemza 的回答对我很有帮助。如果您使用的是 Angular 1.3,他们会稍微改变一下承诺。我在这个问题上卡住了一点,但这是让它起作用的变化:

    if (show) {
      $animate.removeClass(element, 'ng-hide').then(scope.afterShow);
    }
    if (!show) {
      $animate.addClass(element, 'ng-hide').then(scope.afterHide);
    }
    

    Plunker:Code Example

    【讨论】:

      【解决方案3】:

      正如@zeroflagL 所建议的,替换ngShow 的自定义指令可能是要走的路。您可以使用&amp; 将回调传递到指令中,该指令可以在动画完成后调用。为了保持一致性,动画是通过添加和删除 ng-hide 类来完成的,这与通常的 ngShow 指令使用的方法相同:

      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);
              }
            });
          }
        }
      })
      

      监听作用域变量show的示例如下:

      <div my-show="show" after-hide="afterHide()" after-show="afterShow()">...</div>
      

      因为这是添加/删除 ng-hide 类,所以关于动画from the docs about ngShow 的点仍然有效,您需要在 CSS 中添加 display: block !important

      你可以see an example of this in action at this Plunker

      【讨论】:

      • 我在 Plunker 上使用这个并且效果很好 - 但是如果我将角度更改为 1.3 版,则不再触发回调。看起来 addClass 和 removeClass 函数不再需要回调?
      • 没关系,看起来你必须使用 .then(function() {});对于 1.3 版
      • 另外,如果你要使用css动画,一定要在element'ng-hide'之后添加{tempClasses: 'ng-hide-animate'}作为第三个参数,然后再调用.then,如上所述评论。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多