Vous pouvez utiliser .animation
de définir des animations qui sont basé sur Javascript. Par exemple, les fonctions que vous définissez comme les valeurs de addClass
et removeClass
app.animation('.fade', [function() {
return {
addClass: function(element, className, doneFn) {
},
removeClass: function(element, className, doneFn) {
}
};
}]);
sont appelés par Angulaire lorsqu'il détecte que vous êtes de l'ajout ou de la suppression d'une classe à partir d'un élément, à partir de l'une des méthodes:
-
{{ }}
interpoation dans un modèle. E. g. <span class="{{shouldFade ? 'fade' : ''}}">....
- À l'aide de
ng-class
dans un modèle. E. g. <span ng-class="{fade: shouldFade}">...
- À l'aide de l'
$animate
service dans une directive. E. g. $animate.addClass(element, 'fade')
ou $animate.removeClass(element, 'fade')
Quel est le nom de la classe? C'est la classe que je veux appliquer tout en diffusant? La classe que j'attends?
Dans cet exemple, il sera fade
. Un peu bizarre, certes, comme dans l'exemple, il est déjà clair que c'est le nom de la classe concernés. Cependant, si dans le même abrégé du cycle, vous êtes à l'ajout de plusieurs classes à la même élément, alors la concaténation d'entre eux sont passés comme cette chaîne.
Qu'est-ce que doneFn censé être? Je suppose que c'est une fonction qui est exécutée une fois l'animation terminée? Ce qui se passe là-dedans?
C'est une fonction que vous appelez une fois quel que soit le Javascript animation que vous définissez est fait. Par exemple, pour définir une animation qui ne fait rien comme tout:
addClass: function(element, className, doneFn) {
doneFn();
},
L'appelant dit Angulaire que l'animation est terminée. Ce sera, entre autres choses, de supprimer l' ng-animate
classe de l'élément.
Que dois-je faire dans le addClass et removeClass fonction alors, si j'ai déjà un doneFn?
Vous mettez en eux un peu de code, peut-être à l'aide de délais d'attente ou une 3ème partie de la bibliothèque, pour changer l'élément en quelque sorte. Lorsque vous avez fini, vous appelez doneFn
. Par exemple, un 1 étape d'opacité "animation":
addClass: function(element, className, doneFn) {
element.css('opacity', 0.5);
setTimeout(function() {
doneFn();
}, 1000);
},
Je voudrais générer un travail d'animation directement à l'aide Angulaire du ngAnimate module, soit avec CSS ou JS.
Ce n'est pas vraiment ont beaucoup à faire avec les réponses ci-dessus! Si je faisais un réel cas, je soupçonne fortement que je de position les éléments absolument, comme rien d'autre (que je pense) au moins, c'est un peu trop compliqué.
Toutefois, si vous ne voulez vraiment de la chaîne d'animations à l'aide de ngAnimate, une voie possible est d'utiliser le fait qu' $animate.addClass
et $animate.removeClass
retourne une promesse quand il se termine. Afin de chaîne sur la fin d'une telle promesse retourné lors de masquer un élément, il doit être appelé à partir d'un type de situation centrale, et de garder trace de l'élément est visible, masqué, et d'être montré.
Une façon de le faire est d'utiliser 2 des directives sur mesure. Sur chaque élément pour afficher et masquer, qui pourraient être utilisés comme beaucoup ngShow
. L'autre sera un parent directive qui permettra à un seul élément à être visible à tout moment, et de la chaîne de suppression de l' ng-hide
de la classe (et associés animations) après addition d' ng-hide
. Les directives devront communiquer, pourrait être appelé quelque chose comme ngShowUnique
et ngShowUniqueController
, comme dans l'exemple suivant.
<div ng-show-unique-controller>
<h1 class="fade" ng-repeat="child in parent.children" ng-show-unique="parent.activeChild == child">@{{child.title}}</h1>
</div>
et ils pourraient être mises en œuvre comme ci-dessous.
app.directive('ngShowUniqueController', function($q, $animate) {
return {
controller: function($scope, $element) {
var elements = [];
var expressions = [];
var watchers = [];
var unregisterWatchers = null;
var visibleElement = null;
function registerWatchers() {
unregisterWatchers = $scope.$watchGroup(expressions, function(vals) {
var newCurrentIndex = vals.indexOf(true);
var addPromise;
if (visibleElement) {
// Set a fixed height, as there is a brief interval between
// removal of this class and addition of another
$element.css('height', $element[0].getBoundingClientRect().height + 'px');
addPromise = $animate.addClass(visibleElement, 'ng-hide');
} else {
addPromise = $q.when();
}
visibleElement = elements[newCurrentIndex] || null;
if (!visibleElement) return;
addPromise.then(function() {
if (visibleElement) {
$animate.removeClass(visibleElement, 'ng-hide').then(function() {
$element.css('height', '');
});
}
})
});
}
this.register = function(element, expression) {
if (unregisterWatchers) unregisterWatchers();
elements.push(element[0]);
expressions.push(expression);
registerWatchers();
// Hide elements initially
$animate.addClass(element, 'ng-hide');
};
this.unregister = function(element) {
if (unregisterWatchers) unregisterWatchers();
var index = elements.indexOf(element[0]);
if (index > -1) {
elements.splice(index, 1);
expressions.splice(index, 1);
}
registerWatchers();
};
}
};
});
app.directive('ngShowUnique', function($animate) {
return {
require: '^ngShowUniqueController',
link: function(scope, element, attrs, ngShowUniqueController) {
ngShowUniqueController.register(element, function() {
return scope.$eval(attrs.ngShowUnique);
});
scope.$on('$destroy', function() {
ngShowUniqueController.unregister(element);
});
}
};
});
Ceci peut être vu à http://plnkr.co/edit/1eJUou4UaH6bnAN0nJn7?p=preview . Je dois l'avouer, c'est un peu faffy.