如何以多种方式让Angular的ng-switch animate(enter/leave)

How to make Angular ng-switch animate(enter/leave) in more than one way?

本文关键字:animate ng-switch enter leave Angular 方式      更新时间:2023-09-26

我写了一个名为'cardViewer'的angular指令,它可以用动画显示里面的图像。

当你按下"上一页"按钮时,图像向左滑动。当你按下"下一步"按钮时,图像会向右滑动。

我尝试用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有多种输入/离开方式?

问题是ngSwitchngClass有机会执行之前破坏了当前图像的作用域,并在动画开始之前将该图像的类从toRight更改为toLeft(反之亦然)。

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

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

例如,你的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);
};

这是一个叉子,你的plunk显示它工作。打开控制台,查看ngClass添加类和ngSwitch销毁和创建作用域时的日志消息。

我留下了你原来的"下一个"answers"prev"按钮,只是添加了"下一个(固定)"answers"prev(固定)"按钮,这样你就可以比较日志消息,看看如何,使用原始按钮,ngSwitch破坏ngClass执行之前的范围,而在固定版本ngClass执行之前ngSwitch破坏范围。