Angular JS:由指令提供的临时禁用动画,因此当页面加载时它没有动画?

时间:2013-02-22 03:16:22

标签: jquery animation angularjs directive

作为标题,请看这个小提琴:

http://jsfiddle.net/goodwill/ezNuj/

我添加了一个带有以下代码的指令:

myApp.directive('ngFadeIn', function() {
  return function(scope, element, attr) {
    if (element.is('tr, tbody')) {
      element.find('td').effect("highlight", {}, 500);
    } else {
      element.effect("highlight", {}, 500);
    }
    return scope.destroy = function(complete) {
      return element.fadeOut(500, function() {
        if (complete) {
          return complete.apply(scope);
        }
      });
    };
  };
});

我遇到的问题是首次加载页面时,因为我在ng-repeat元素中应用了该指令,所有项目在首次加载页面时都会突出显示效果(闪烁一次)。如何在没有太多黑客的情况下跳过此效果(理想情况下,在指令中完成所有操作)

4 个答案:

答案 0 :(得分:0)

有趣的是,我不确定是否有一个简单,干净的解决方案。似乎ngRepeatDirective构建时不关心转发器是第一次运行还是只是将新项添加到列表中。因此,它不会让你采取不同的行动取决于那。 AngularUI的ui-animate指令似乎也没有解决这个问题,所以我不确定这是否可行,而不诉诸于讨厌的超时。

您可以做的是修改ngRepeatDirective以检查类似ng-repeat-finished属性的内容,并在转发器完成后执行该属性。然后,添加逻辑以避免第一个转发器上的动画应该是微不足道的。

顺便说一下,你不应该用ng前缀命名你的指令,因为这是Angular在内部使用的。你应该为你的应用程序提出自己的前缀。

答案 1 :(得分:0)

如果我们可以确定页面第一次完成渲染的时间,那么我们可以在服务或rootScope上设置一些属性,您的指令可以注入该属性,因此检查此属性以确定是否应用动画

不幸的是,似乎没有办法确定页面何时完成渲染。请参阅AngularJS - How to query the DOM when directive rendering is complete,该问题正在解决同一问题。

我能想到的唯一解决方法是创建另一个指令(在页面上使用一次),使用$ timeout简单地延迟1秒左右,然后执行我上面提到的:在服务上设置一些属性或rootScope。你的fadeIn指令会监视那个属性/变量,当值改变时,它可以设置一些允许或阻止动画的局部属性/布尔/标志。

答案 2 :(得分:0)

我会检查刚刚在version 1.1.14中发布的角度内置动画。以下是关于新功能的精彩文章:Animation in AngularJS。特别是我会查看“有条件地启用/禁用动画”部分。从他们的网站:

JS:

//turn on the animation
$scope.myAnimation = { enter: 'cool-enter', leave: 'cool-leave' };

//change the animation
$scope.myAnimation = { enter: 'uncool-enter', leave: 'uncool-leave' };

//remove the animation
$scope.myAnimation = null;

HTML:

<div data-some-directive data-ng-animate="myAnimation"></div>

再次注意,这需要当前不稳定版本的角度js 1.1.14

答案 3 :(得分:0)

我使用angular 1.4.9也有同样的问题。 我不想第一次发生ng-repeat动画。 我发现做这项工作的唯一方法是在ng-repeat父项上使用自定义指令并在短时间内禁用动画:

(function (){
  'use strict';

  angular
    .module('directives')
    .directive('disableLoadingAnimation', disableLoadingAnimation);

  function disableLoadingAnimation($animate, $timeout) {
    var directive = {
      link: link,
      restrict: 'A'
    };
    return directive;

    function link(scope, element) {
      $animate.enabled(element, false);
      $timeout(function (){
        $animate.enabled(element, true);
      }, 1000);
    }
  }
})();

HTML

<table disable-loading-animation>
   <tr ng-repeat="line in lines">...</tr>
</table>

我不喜欢这样一个事实,即我必须设置1000毫秒的延迟,但这是我迄今为止发现的更清洁的方式。