Ng-Animate: Conditionally Switching "Back" Transition (Bug)

ng-animate : conditionally switching back transition (BUG?)

Ok, so based on the comments I'm pretty sure you want the incoming page to also determine exit animations to apply to the outgoing page. So you really need your $locationChange code.

It also looks like the problem you are seeing is that you are setting a class on the parent independently on the incoming page but there is nothing to keep the animations waiting for this class change to occur.

The simplest fix seems to be to make the ng-animate depend on your changing variable to determine the animation class names:

<ng-view ng-animate="transitionClass"></ng-view>

then the CSS selectors just collapse into single classes:

.LR-enter-active {
...
}

(where transitionClass is still being set on the $rootScope in the locationChangeStart:)

 $rootScope.$on("$locationChangeStart", function (event, next, current) {
...

http://jsfiddle.net/9XPVX/4/

How to animate :enter & :leave transitions conditionally in Angular?

According to Angular IO:

When true, the special animation control binding @.disabled binding prevents all animations from rendering. Place the @.disabled binding on an element to disable animations on the element itself, as well as any inner animation triggers within the element.

The following example shows how to use this feature:

@Component({
selector: 'my-component',
template: `
<div [@.disabled]="isDisabled">
<div [@childAnimation]="exp"></div>
</div>
`,
animations: [
trigger("childAnimation", [
// ...
])
]
})
class MyComponent {
isDisabled = true;
exp = '...';
}

When @.disabled is true, it prevents the @childAnimation trigger from animating, along with any inner animations.

Conditionally animating ng-view transitions

An alternative solution that doesn't require much code is to define your animations on your routes:

$routeProvider.when('/view1', {
templateUrl: 'view1.html',
controller: 'View1Controller',
animations: {
enter: 'enter-left',
leave: 'leave-left'
}
});

Then use a directive to retrieve the current route's animations and add them to the element:

app.directive('viewAnimations', function ($route) {
return {
restrict: 'A',
link: function (scope, element) {
var animations = $route.current.animations;
if (!animations) return;

if (animations.enter) element.addClass(animations.enter);
if (animations.leave) element.addClass(animations.leave);
}
};
});

And put the directive on the element that contains the ngView directive:

<body ng-view view-animations></body>

Demo: http://plnkr.co/edit/Y3ExDyiPIJwvVKO4njBT?p=preview

Edit: New solution.

To set animations during run-time I would use a service just like you are doing, but a directive to apply them.

Very basic example of service:

app.factory('viewAnimationsService', function ($rootScope) {

var enterAnimation;

var getEnterAnimation = function () {
return enterAnimation;
};

var setEnterAnimation = function (animation) {
enterAnimation = animation;
};

var setLeaveAnimation = function (animation) {
$rootScope.$emit('event:newLeaveAnimation', animation);
};

return {
getEnterAnimation: getEnterAnimation,
setEnterAnimation: setEnterAnimation,
setLeaveAnimation: setLeaveAnimation
};
});

And the directive:

app.directive('viewAnimations', function (viewAnimationsService, $rootScope) {
return {
restrict: 'A',
link: function (scope, element) {

var previousEnter, previousLeave;

var enterAnimation = viewAnimationsService.getEnterAnimation();
if (enterAnimation) {
if (previousEnter) element.removeClass(previousEnter);
previousEnter = enterAnimation;
element.addClass(enterAnimation);
}

$rootScope.$on('event:newLeaveAnimation', function (event, leaveAnimation) {
if (previousLeave) element.removeClass(previousLeave);
previousLeave = leaveAnimation;
element.addClass(leaveAnimation);
});
}
};
});

Demo: http://plnkr.co/edit/DuQXaN2eYgtZ725Zqzeu?p=preview

Transition using ng-animate not working in 1.2.16

Angular changed the way animations work in 1.2+.
Animation is now a separate module that needs to be added.

There is a very nice guide on 1.2+ animations found here:

http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html

Edit: In that link they also talk about what has changed from 1.1.5 to 1.2 it will help you understand the changes.

var app = angular.module('myApp', ['ngAnimate']);
app.controller('MainController', ['$scope', function ($scope) {
$scope.items = [1,2,3,4,5,6,7,8,9];

$scope.replaceItem = function() {
$scope.items.shift();
$scope.items.push(Math.floor(Math.random()*1000000000));
};
}]);

Solution in fiddle: http://jsfiddle.net/dxQqm/166

Angular animate if condition is met

Solution 1:

You can disable animations using:

  @HostBinding('@.disabled')
public animationsDisabled = false;

This set to your component the css class: ng-animate-disabled

See an example here toggling the checkbox "Toggle All Animations"

Solution 2:
To avoid animations in and out at the same time, you can use sequence() to run animations in given order.

trigger('slideInOut', [
transition('* => *', [
sequence([
query(':enter', [
style({transform: 'translateY(-100%)'}),
animate('200ms ease-in', style({transform: 'translateY(0%)'}))
], {optional: true}),
query(':leave', [
animate('200ms ease-in', style({transform: 'translateY(-100%)'}))
], {optional: true})
])
])
])

This will run first animations enter and second animations leave. Change the order in the array if you want the other way round sequence.

Make sure you annotate the parent with @slideInOut, not the item element.

<parent @slideInOut>
<ion-item color="primary" *ngIf="openElement1" lines="none">
</ion-item>
<ion-item color="primary" *ngIf="openElement2" lines="none">
</ion-item>
</parent>


Related Topics



Leave a reply



Submit