javascript - 无法更新 ng-repeat 离开动画的范围

标签 javascript jquery angularjs animation

我在 ng-repeat 上有一个 Angular 动画(使用 jQuery 的动画函数),并且希望在每个动画完成时更新模型上的“可见”属性。目的是编排多个动画。我发现这在输入函数中工作正常,但在离开函数中不起作用。这是代码:

app.animation('.step-animation',
  function () {
    return {
      enter: function (element, done) {
        var scope = angular.element(element).scope();

        jQuery(element).css({ opacity: 0 });
        jQuery(element).animate({
          opacity: 1
        }, 2000, done);

        return function (cancelled) {
          if (cancelled) {
            jQuery(element).stop();
          } else {
            scope.$apply(function () {
              scope.step.Visible = true;
            });
          }
        }
      },
      leave: function(element, done) {
        var scope = angular.element(element).scope();

        jQuery(element).animate({
          opacity: 0
        }, 1000, done);

        return function (cancelled) {
          if (cancelled) {
            jQuery(element).stop();
          } else {
            scope.$apply(function () {
              scope.step.Visible = false;
            });
          }
        }
      }
    }
  });

进入动画完成后,我的步骤对象上的 Visible 属性已成功设置为 true,但在离开动画时并未更新。另外 - 我注意到 $parent 属性在 left 函数的范围内为 null,但在 Enter 函数的范围内填充。看起来离开是孤立的,而进入则不是。如何从休假功能更新范围?

更新

我发现 return 函数在leave 函数中被调用了两次——一次canceled = true。不知道是什么原因造成的,也不知道如何排除故障。

最佳答案

对于迭代集合中的每个元素,将呈现一个 DOM 模板,并创建一个新范围并与其关联。

当这些模板之一从 DOM 中删除时(例如由于 filter),代码中的 leave 函数就会被调用。当模板被删除时,其关联的范围将被销毁。

这意味着当以下函数执行时,关联的作用域将已经被销毁:

return function (cancelled) {
  if (cancelled) {
    jQuery(element).stop();
  } else {
    scope.$apply(function () {
      scope.step.Visible = false;
    });
  }
};

您可以通过在其中添加以下内容来验证这一点:

console.log(scope.$$destroyed);

当作用域被销毁时,会发生以下情况之一:其 $apply 函数被设置为空函数:

function noop() {}

这意味着您传递给 scope.$apply 的匿名函数(将 Visible 设置为 false 的函数)永远不会被执行,因为 $ apply 只是一个空函数,不会对其传递的参数执行任何操作。

要解决此问题,您可以注入(inject) $rootScope 并使用它:

return function(cancelled) {
  if (cancelled) {
    jQuery(element).stop();
  } else {
    $rootScope.$apply(function() {
      scope.step.Visible = false;
    });
  }
};

演示: http://plnkr.co/edit/jdNtcOSzq9BC9vxjmmLy?p=preview

另请注意,element 已经是 jqLit​​e 元素(如果 jQuery 在 AngularJS 之前加载,则为 jQuery 元素),因此您可以替换以下内容:

var scope = angular.element(element).scope();

与:

var scope = element.scope();

以及所有出现的情况:

jQuery(element)

只有:

element

关于javascript - 无法更新 ng-repeat 离开动画的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27671600/

相关文章:

javascript - 如果 child 有特定类(class),如何向父级添加类(class)

javascript - Bootstrap 模式启动递增时间

javascript - 使用 PHP 解析 CSS 文件

javascript - 将参数传递给状态导致元素不显示

javascript - 使用 afterRender 回调后 Angular 渲染不工作

javascript - 来自 csv 数据的新数组

javascript - SlideJS 的宽度和交换不起作用

javascript - ng-repeat 中的按钮每秒更改 10 次,导致其不可点击

javascript - AngularJS 何时将模型更改传播到 DOM?

javascript - TypeScript:在 Promise<T> 中包装函数参数