web-dev-qa-db-fra.com

Comment ajouter conditionnellement des animations dans Angular 2

J'ai un composant de formulaire qui contient des champs, certains champs que je veux animer lorsqu'ils apparaissent dans le formulaire, mais pas tous les champs.

<div *ngFor="let field of form.Fields">
    <div [ngSwitch]="field.Type" [@slideOut]>
        <!-- more field stuff -->
    </div>
</div>

Avec d'autres attributs, je peux faire quelque chose comme ça [attr.required]="field.Required" Mais [attr.@slideOut] ne semble pas fonctionner.

Idéalement, j'aimerais avoir une propriété d'animation sur mon champ afin de pouvoir passer des animations comme celle-ci [@field.Animation] mais je ne trouve aucune documentation sur la façon dont je ferais quelque chose comme ça. Des idées?

14
Devcon

J'ai rencontré un problème similaire et j'ai constaté que vous devez adopter une approche légèrement différente.

Dans Angular, les animations sont liées à l'état. Ainsi, au lieu de définir un déclencheur différent pour votre animation dans votre code HTML, vous souhaitez définir plusieurs états que votre déclencheur peut surveiller dans votre classe de composants. Et plutôt que de déclencher des animations directement à partir d'une méthode, vous définissez l'état de l'objet auquel une animation est liée.

Ainsi, par exemple, je pourrais définir les éléments suivants dans le décorateur de composants après avoir importé les modules nécessaires.

@Component({
  selector: 'app-some-animated',
  templateUrl: './some.component.html',
  styleUrls: ['./some-animated.component.scss'],
  animations: [
    trigger('flyInOut', [
      transition("void => fly", [
        animate(300, keyframes([
          style({transform: 'translateX(100%)', opacity: 0}),
          style({transform: 'translateX(0)', opacity: 1})
        ]))
        ]
      )
    ]),
    trigger('flyInOut', [
      transition("void => fade", [
          animate(300, keyframes([
            style({opacity: 0}),
            style({opacity: 1})
          ]))
        ]
      )
    ])
  ]
})

Dans ce cas, je réalise les animations dès que l'élément est instancié. Et dans la méthode ngOnInit (), je définis this.watchMe sur "fly" ou "fade".

Dans le html, j'attache le déclencheur flyInOut comme ceci:

<div [@flyInOut]="watchMe">
  Some content...
</div>

Dans votre cas, vous souhaiterez probablement ajouter l'état requis à vos objets de champ ou comme condition itérable à partir de votre * ngFor.

Cet article de coursetro a une belle explication et une vidéo aussi.

12
user2528534

Pour activer ou désactiver conditionnellement un déclencheur d'animation, utilisez [@ .disabled] comme indiqué sur https://angular.io/api/animations/trigger#disabling-animations

En prenant l'exemple de l'OP, si chaque champ a une propriété "requis" avec une valeur booléenne et qu'une animation ne doit être appliquée que lorsque cela est vrai, le code peut être:

<div *ngFor="let field of form.Fields">
    <div [@slideOut] [@.disabled]="!field.required">
        <!-- more field stuff -->
    </div>
</div>

Il vaut la peine de dire que l'utilisation de [@ .disabled] sur un composant désactivera également les animations sur tous les composants enfants, par exemple l'apparence d'un menu de matériaux ne sera plus animée.

Si nécessaire, cela peut être évité en utilisant à la place une conditionnelle pour définir la durée de l'animation sur l'animation parent à 0, ce qui supprime (visuellement) l'animation, sans impact sur les composants enfants.

Modèle:

<div *ngFor="let field of form.Fields">
    <div [@slideOut]="field.required ? {value:'', params:{duration : 200}} : {value:'', params:{duration : 0}}">
        <!-- more field stuff -->
    </div>
</div>

Animation:

trigger('slideOut', [
    transition(':enter', [
        style({ opacity: '0' }),
        animate('{{duration}}ms cubic-bezier(0.4, 0.0, 0.2, 1)'),
        style({ opacity: '1' })
    ])
])
2
Matt Saunders