J'essaie d'implémenter une animation slideDown/slideUp avec AngularJS. Je ne peux pas utiliser la transition de CSS3 (malheureusement) car le height
est réglé sur auto
(et je ne veux pas utiliser le max-height
solution ), donc j'essaie d'utiliser la méthode slideToggle
de jQuery.
Étant donné le balisage suivant:
<ul>
<li ng-repeat="entry in data">
<span>{{entry.title}}</span>
<a ng-click="clicked($event)" href>more?</a>
<p>{{entry.description}}</p>
</li>
</ul>
J'ai implémenté la méthode suivante dans mon contrôleur:
$scope.clicked = function($event) {
var a = jQuery($event.target);
var p = a.next();
p.slideToggle();
};
Même si cela semble fonctionner comme prévu, j'ai compris que la modification du DOM se fera exclusivement dans les directives.
Après avoir lu documentation d'AngularJS (ce que je trouve un peu léger à mon humble avis), les directives sont encore un peu vagues pour moi, donc quelqu'un pourrait-il me dire si la directive suivante respecte les meilleures pratiques d'AngularJS ou pas?
.directive('testDirective', [
function() {
return {
restrict: 'A',
scope: {
entry: '=testDirective'
},
template: '<span>{{entry.title}}</span> ' +
'<a ng-click="clicked($event)" href>more?</a>' +
'<p>{{entry.description}}</p>',
link: function(scope, element) {
var p = jQuery(element.find('p'));
scope.clicked = function($event) {
p.slideToggle();
};
}
};
}])
Pourrait-il être amélioré? Suis-je autorisé pour utiliser jQuery dans une directive? Respecte-t-il la séparation des préoccupations?
Alternativement, vous pouvez utiliser le $animate
D'AngularJS:
.animation('.slide', function() {
var NG_HIDE_CLASS = 'ng-hide';
return {
beforeAddClass: function(element, className, done) {
if(className === NG_HIDE_CLASS) {
element.slideUp(done);
}
},
removeClass: function(element, className, done) {
if(className === NG_HIDE_CLASS) {
element.hide().slideDown(done);
}
}
}
});
Utilisez ng-hide
Ou ng-show
Pour afficher ou masquer la description.
<li ng-repeat="entry in data">
<span>{{entry.title}}</span>
<a ng-click="expand = !expand" href="#">more?</a>
<p class="slide" ng-show="expand">{{entry.description}}</p>
</li>
Voir JSFiddle
P.S. vous devez inclure jquery
et angular-animate.js
Je veux montrer un exemple de la façon dont cela se fait avec ng-if
, car je cherchais une solution pendant des heures dans plusieurs approches complètement différentes qui fonctionnent avec ng-show
seulement. Vous pouvez utiliser ng-if
contre ng-show
si vous avez besoin de directives initialisées uniquement lorsqu'elles deviennent visibles.
Pour utiliser jQuery slideDown/slideUp avec ng-if
, vous pouvez également utiliser ngAnimate
mais en utilisant différents crochets: enter
et leave
.
app.animation('.ng-slide-down', function() {
return {
enter: function(element, done) {
element.hide().slideDown()
return function(cancelled) {};
},
leave: function(element, done) {
element.slideUp();
},
};
});
<div class="ng-slide-down" ng-if="isVisible">
I will slide down upon entering the DOM.
</div>
Cela a été étonnamment difficile à réaliser, même en essayant diverses approches basées sur JS et uniquement des approches CSS. En fin de compte, il y a un temps et un lieu pour les animations de jQuery.