我编写了一个名为“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上执行。
要使其正常工作,您只需要更新next
和prev
方法,即可在设置displayCard
和$timeout
后将它们的toLeft
属性设置为toRight
,因此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您的朋克叉显示它正在工作。打开控制台以查看
ngClass
添加您的类以及ngSwitch
销毁和创建范围的日志消息。我将原来的“下一个”和“上一个”按钮留在那里,只是添加了“下一个(固定)”和“上一个(固定)”按钮,以便您可以比较日志消息,并了解
ngSwitch
如何使用原始按钮破坏范围在ngClass
执行之前,而在固定版本中,ngClass
在ngSwitch
销毁作用域之前执行。