açısal 2 ngIf ve CSS geçiş / animasyon


121

Bir div'in css kullanarak açısal 2'de sağdan kaymasını istiyorum.

  <div class="note" [ngClass]="{'transition':show}" *ngIf="show">
    <p> Notes</p>
  </div>
  <button class="btn btn-default" (click)="toggle(show)">Toggle</button>

Sınıfı değiştirmek ve opaklığı kullanmak için yalnızca [ngClass] kullanırsam iyi çalışırım. Ama o öğenin baştan oluşturulmasını istemiyorum, bu yüzden onu ilk önce ngIf ile "gizlerim", ama sonra geçiş çalışmaz.

.transition{
  -webkit-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  -moz-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  -ms-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out ;
  -o-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  margin-left: 1500px;
  width: 200px;
  opacity: 0;
}

.transition{
  opacity: 100;
  margin-left: 0;
}

Yanıtlar:


195

4.1.0 güncellemesi

Plunker

Ayrıca bkz. Https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24

2.1.0 güncellemesi

Plunker

Daha fazla ayrıntı için angular.io'daki Animasyonlar'a bakın .

import { trigger, style, animate, transition } from '@angular/animations';

@Component({
  selector: 'my-app',
  animations: [
    trigger(
      'enterAnimation', [
        transition(':enter', [
          style({transform: 'translateX(100%)', opacity: 0}),
          animate('500ms', style({transform: 'translateX(0)', opacity: 1}))
        ]),
        transition(':leave', [
          style({transform: 'translateX(0)', opacity: 1}),
          animate('500ms', style({transform: 'translateX(100%)', opacity: 0}))
        ])
      ]
    )
  ],
  template: `
    <button (click)="show = !show">toggle show ({{show}})</button>

    <div *ngIf="show" [@enterAnimation]>xxx</div>
  `
})
export class App {
  show:boolean = false;
}

orijinal

*ngIfifade olduğunda öğeyi DOM'dan kaldırır false. Var olmayan bir öğede geçiş yapamazsınız.

Bunun yerine kullanın hidden:

<div class="note" [ngClass]="{'transition':show}" [hidden]="!show">

2
Evet, gizli onu yalnızca görünmez kılar, ancak öğe hala mevcuttur. *ngIftamamen DOM'dan kaldırır.
Günter Zöchbauer

1
Gibi display:none. display:hiddenAFAIK yok .
Günter Zöchbauer

1
@ GünterZöchbauer evet, opaklık Donanım hızlandırılmış olduğundan daha iyi uyacaktır.
Ændri Domi 01

1
Boşver. opaklık, öğeyi kaldırmayacak ve alttaki öğeleri de kapsamaya devam edecektir, ekran: yok; ama güzel bir geçişle.
OP'ye

1
Tetikleyici, stil, animasyon ve geçiş öğeleri artık @ angular / animations'tan eklenmelidir. Yani { trigger, style, animate, transition } from '@angular/animations';
Joel Hernandez

137

En son açısal 2 belgelerine göre "Giriş ve Ayrılma" öğelerini canlandırabilirsiniz (açısal 1'deki gibi).

Basit kararma animasyonuna örnek:

İlgili @Component içinde ekleyin:

animations: [
  trigger('fadeInOut', [
    transition(':enter', [   // :enter is alias to 'void => *'
      style({opacity:0}),
      animate(500, style({opacity:1})) 
    ]),
    transition(':leave', [   // :leave is alias to '* => void'
      animate(500, style({opacity:0})) 
    ])
  ])
]

İthalat eklemeyi unutmayın

import {style, state, animate, transition, trigger} from '@angular/animations';

İlgili bileşenin html öğesi şöyle görünmelidir:

<div *ngIf="toggle" [@fadeInOut]>element</div>

Burada slayt ve karartma animasyonu örneği oluşturdum .

Açıklama 'boşluk' ve üzerinde '*':

  • voidngIffalse değerine ayarlandığı durumdur (öğe bir görünüme eklenmediğinde geçerlidir).
  • *- Birçok animasyon durumu olabilir (belgelerde daha fazlasını okuyun). Durum *, bir "joker karakter" olarak hepsinden önceliklidir (benim örneğimde bu, ngIfolarak ayarlandığı durumdur true).

Uyarı (açısal belgelerden alınmıştır):

Uygulama modülünün içinde ekstra beyan, import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

Açısal animasyonlar, standart Web Animasyonları API'sinin üzerine oluşturulur ve onu destekleyen tarayıcılarda yerel olarak çalışır. Diğer tarayıcılar için bir polyfill gereklidir. GitHub'dan web-animations.min.js'yi alın ve sayfanıza ekleyin.


2
Açısal animasyonları kullanmak için BrowserAnimationsModule'u içe aktarmanız gerekir. Yanılmıyorsam, animasyon modülü kendi modülüne taşınmadan önce açısal 2'nin çekirdek modülünde bulundu, bu nedenle içe aktarım olmadan birçok plunker örneği buluyorsunuz. İçe aktarımla ilgili güncellenmiş bir plnkr: Link
snaplemouton

1
Böyle bir yaklaşım kullanılırken leaveanimasyon gerçekleşmez çünkü bileşen bundan *ngIfönce DOM'den kaldırılır .
Slava Fomin II

4
Bu kabul edilen cevap olmalı, aslında çözümü ngIf kullanmak isteyenlere veriyor, diğer geçici çözümleri değil.
Ovi Trif

17
    trigger('slideIn', [
      state('*', style({ 'overflow-y': 'hidden' })),
      state('void', style({ 'overflow-y': 'hidden' })),
      transition('* => void', [
        style({ height: '*' }),
        animate(250, style({ height: 0 }))
      ]),
      transition('void => *', [
        style({ height: '0' }),
        animate(250, style({ height: '*' }))
      ])
    ])

11

Modern tarayıcılar için yalnızca CSS çözümü

@keyframes slidein {
    0%   {margin-left:1500px;}
    100% {margin-left:0px;}
}
.note {
    animation-name: slidein;
    animation-duration: .9s;
    display: block;
}

Yalnızca CSS geçişine girmek için iyi bir alternatif . Bunu, ng-entersınıf kullanımından geçiş için geçici bir çözüm olarak kullandı .
edmundo096

4

Bir yol, ngIf özelliği için bir ayarlayıcı kullanmak ve durumu, değerin güncellenmesinin bir parçası olarak ayarlamaktır.

StackBlitz örneği

fade.component.ts

 import {
    animate,
    AnimationEvent,
    state,
    style,
    transition,
    trigger
  } from '@angular/animations';
  import { ChangeDetectionStrategy, Component, Input } from '@angular/core';

  export type FadeState = 'visible' | 'hidden';

  @Component({
    selector: 'app-fade',
    templateUrl: './fade.component.html',
    styleUrls: ['./fade.component.scss'],
    animations: [
      trigger('state', [
        state(
          'visible',
          style({
            opacity: '1'
          })
        ),
        state(
          'hidden',
          style({
            opacity: '0'
          })
        ),
        transition('* => visible', [animate('500ms ease-out')]),
        transition('visible => hidden', [animate('500ms ease-out')])
      ])
    ],
    changeDetection: ChangeDetectionStrategy.OnPush
  })
  export class FadeComponent {
    state: FadeState;
    // tslint:disable-next-line: variable-name
    private _show: boolean;
    get show() {
      return this._show;
    }
    @Input()
    set show(value: boolean) {
      if (value) {
        this._show = value;
        this.state = 'visible';
      } else {
        this.state = 'hidden';
      }
    }

    animationDone(event: AnimationEvent) {
      if (event.fromState === 'visible' && event.toState === 'hidden') {
        this._show = false;
      }
    }
  }

fade.component.html

 <div
    *ngIf="show"
    class="fade"
    [@state]="state"
    (@state.done)="animationDone($event)"
  >
    <button mat-raised-button color="primary">test</button>
  </div>

example.component.css

:host {
  display: block;
}
.fade {
  opacity: 0;
}

3

Açısal 5 kullanıyorum ve bir ngfor'da benim için çalışacak bir ngif için animateChild kullanmam gerekiyordu ve kullanıcı detayı bileşeninde kullanıcıyı gizlemek için * ngIf = "user.expanded" kullandım ve girmek için çalıştı ayrılma

 <div *ngFor="let user of users" @flyInParent>
  <ly-user-detail [user]= "user" @flyIn></user-detail>
</div>

//the animation file


export const FLIP_TRANSITION = [ 
trigger('flyInParent', [
    transition(':enter, :leave', [
      query('@*', animateChild())
    ])
  ]),
  trigger('flyIn', [
    state('void', style({width: '100%', height: '100%'})),
    state('*', style({width: '100%', height: '100%'})),
    transition(':enter', [
      style({
        transform: 'translateY(100%)',
        position: 'fixed'
      }),
      animate('0.5s cubic-bezier(0.35, 0, 0.25, 1)', style({transform: 'translateY(0%)'}))
    ]),
    transition(':leave', [
      style({
        transform: 'translateY(0%)',
        position: 'fixed'
      }),
      animate('0.5s cubic-bezier(0.35, 0, 0.25, 1)', style({transform: 'translateY(100%)'}))
    ])
  ])
];

0

Benim durumumda yanlışlıkla yanlış bileşen üzerindeki animasyonu ilan ettim.

app.component.html

  <app-order-details *ngIf="orderDetails" [@fadeInOut] [orderDetails]="orderDetails">
  </app-order-details>

( appComponent.ts) Öğesinin kullanıldığı bileşende animasyonun bildirilmesi gerekir . Onun OrderDetailsComponent.tsyerine animasyonu açıklıyordum.

Umarım aynı hatayı yapan birine yardımcı olur

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.