javascript - 如何以多种方式使 Angular ng-switch 动画(进入/离开)?

标签 javascript angularjs angularjs-directive angularjs-animation ng-switch

我编写了一个名为“cardViewer”的 Angular Directive(指令),它可以用动画显示其中的图像。

当您按“上一页”按钮时,图像向左滑动。当您按“下一步”按钮时,图像向右滑动。

我尝试使用 ng-switch 来实现此目的,它仅支持 .ng-enter.ng-leave 动画类。但我需要两种进入方式(从左进入和从右进入),两种离开方式(从左离开和右离开)。

所以我尝试ng-class来解决这个问题。我希望它可以在切换之前添加 toLeft 类,这样它就可以应用特定的CSS动画。

但它似乎无法正常工作。当我按“下一步”按钮两次时,它工作正常。但是当我按“下一个”,然后按“上一个”时,新图像以正确的方向进入,但旧图像以错误的方向离开。

我的指令模板:

<h1>hahaha</h1>
  <div>
    <button ng-click='prev()'>prev</button>
    <button ng-click='next()'>next</button>
  </div>
<div>current Card Index: {{displayCard}}</div>

<div class="card-container" ng-switch="displayCard">
<img class="card"
   src="http://i.imgur.com/EJRdIcf.jpg" ng-switch-when="1" 
   ng-class="{'toLeft': toLeft, 'toRight': toRight}"/>
<img class="card"
   src="http://i.imgur.com/StaoX5y.jpg" ng-switch-when="2" 
   ng-class="{'toLeft': toLeft, 'toRight': toRight}"/>
<img class="card"
   src="http://i.imgur.com/eNcDvLE.jpg" ng-switch-when="3" 
   ng-class="{'toLeft': toLeft, 'toRight': toRight}"/>
</div>

指令:

angular.module('app', ['ngAnimate'])
  .directive('cardViewer', function() {

  return {
    templateUrl: 'cardViewer.html',
    link: function(scope, element, attr) {
      scope.toLeft = false;
      scope.toRight = false;

      scope.displayCard = 1;

      //when press prev, card slide to left
      scope.prev = function() {
        scope.toLeft = true;
        scope.toRight = false;
        if (scope.displayCard == 1) {
          scope.displayCard = 3
        } else {
          scope.displayCard -= 1;
        }
      };

      //when press prev, card slide to right
      scope.next = function() {
        scope.toLeft = false;
        scope.toRight = true;

        if (scope.displayCard == 3) {
          scope.displayCard = 1
        } else {
          scope.displayCard += 1;
        }
      };
    }
  }
});

CSS:

.card-container {
  position: relative;
  height: 500px;
  overflow: hidden;
}
.card {
  width: 100%;
  position: absolute;
}

.card.ng-animate {
  transition: 1s linear all;
}

.card.ng-enter.toLeft {
  left: 100%;
}
.card.ng-enter-active.toLeft {
  left: 0;
}
.card.ng-leave.toLeft {
  left: 0;
}
.card.ng-leave-active.toLeft {
  left: -100%;
}

.card.ng-enter.toRight {
  left: -100%;
}

.card.ng-enter-active.toRight {
  left: 0;
}

.card.ng-leave.toRight {
  left: 0;
}

.card.ng-leave-active.toRight {
  left: 100%;
}

这是我的笨蛋:cardViewer

我的代码有什么问题吗?让 ng-switch 以多种方式进入/离开的正确方法是什么?

最佳答案

问题在于,在动画开始之前,ngSwitch 有机会执行并将该图像的类从 ngClass 更改为 toRight(反之亦然)之前,toLeft 正在破坏当前图像的范围。

ngSwitch 创建一个新作用域并以优先级 1200 执行,而 ngClass 以优先级 0 执行。

要使其工作,您只需更新 nextprev 方法,以便它们在 displayCard 中设置 $timeout 属性,在设置 toLefttoRight 后,因此 ngClass 有机会对之前的新 toLeft/toRight 设置ngSwitch 破坏了该范围。

例如,您的 next 方法将如下所示:

scope.next = function() {
  scope.toLeft = false;
  scope.toRight = true;

  // need to do this in a $timeout so ngClass has 
  // chance to update the current image's class based 
  // on the new toLeft and toRight settings before
  // ngSwitch acts on the new displayCard setting
  // and destroys the current images's scope.
  $timeout(function () {
    if (scope.displayCard == 3) {
      scope.displayCard = 1
    } else {
      scope.displayCard += 1;
    }
  }, 0);
};

Here's 一个 fork ,显示它正在工作。打开控制台以查看 ngClass 添加类以及 ngSwitch 销毁并创建作用域时的日志消息。

我将原来的“下一个”和“上一个”按钮留在那里,只是添加了“下一个(固定)”和“上一个(固定)”按钮,以便您可以比较日志消息并查看如何使用原始按钮,ngSwitchngClass 执行之前销毁作用域,而在固定版本中,ngClassngSwitch 销毁作用域之前执行。

关于javascript - 如何以多种方式使 Angular ng-switch 动画(进入/离开)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32919405/

相关文章:

javascript - 如何在扩展后台页面访问localStorage?

javascript - 以python 'JSON Array of arrays'格式遍历 'List of lists'

javascript - 防止 node_modules 包更新的最佳方法

javascript - 具有多个过滤器选项的 Angular ng-repeat

javascript - 最大化 ng-app 中的 div

angularjs - 通过 UI-Grid cellTemplate 渲染的指令不正确

javascript - Angularjs 服务方法未被调用,TypeError : Cannot read property '

javascript - Node JS HTTP 服务器 request.on ('data' ) 事件失败

javascript - AngularJs 工具提示指令 - 添加样式

angular - 为什么我们将 [formGroup] 指令应用于方括号下的表单,而对于表单字段,我们应用不带方括号的 formControlName 指令?