Angular 2 ngIf и переход/анимация CSS
Я хочу, чтобы div сместился справа в angular 2 с помощью css.
<div class="note" [ngClass]="{'transition':show}" *ngIf="show">
<p> Notes</p>
</div>
<button class="btn btn-default" (click)="toggle(show)">Toggle</button>
Я отлично работаю, если я использую [ngClass] для переключения класса и использования непрозрачности.
Но я не хочу, чтобы этот элемент отображался с самого начала, поэтому сначала "спрячу" его с ngIf, но затем переход не будет работать.
.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;
}
Ответы
Ответ 1
обновление 4.1.0
Plunker
Смотрите также https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24
обновление 2.1.0
Plunker
Для получения дополнительной информации см. Анимации на angular.io.
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;
}
оригинальный
*ngIf
удаляет элемент из DOM, когда выражение становится false
. У вас не может быть перехода на несуществующий элемент.
Используйте вместо этого hidden
:
<div class="note" [ngClass]="{'transition':show}" [hidden]="!show">
Ответ 2
В соответствии с последней документацией angular 2 выможете анимировать элементы "Ввод и отъезд" (как в angular 1).
Пример простой анимации затухания:
В соответствующем @Component добавить:
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}))
])
])
]
Не забудьте добавить импорт
import {style, state, animate, transition, trigger} from '@angular/animations';
Соответствующий HTML-элемент компонента должен выглядеть следующим образом:
<div *ngIf="toggle" [@fadeInOut]>element</div>
Я создал пример слайд-анимации здесь.
Объяснение на "void" и "*":
void
- это состояние, когда для ngIf
установлено значение false (оно применяется, когда
элемент не прикреплен к представлению).
*
- Может быть много состояний анимации (подробнее в документации). Состояние *
имеет приоритет над всеми ними как "подстановочный знак" (в моем примере это состояние, когда для ngIf
установлено значение true
).
Примечание (взято из angular документов):
Дополнительная декларация внутри модуля приложения,
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
Angular анимации построены поверх стандартного API веб-анимаций и запускать изначально в браузерах, которые его поддерживают. Для других браузеров полифилл обязателен. Возьмите web-animations.min.js из GitHub и добавьте это на вашу страницу.
Ответ 3
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: '*' }))
])
])
Ответ 4
Решение только для CSS для современных браузеров
@keyframes slidein {
0% {margin-left:1500px;}
100% {margin-left:0px;}
}
.note {
animation-name: slidein;
animation-duration: .9s;
display: block;
}
Ответ 5
Я использую angular 5 и для ngif для работы для меня, который находится в ngfor, мне пришлось использовать animateChild, а в компоненте user-detail я использовал * ngIf = "user.expanded", чтобы показать скрытый пользователь и он работал для входа в отпуск
<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%)'}))
])
])
];
Ответ 6
Одним из способов является использование установщика для свойства ngIf и установка состояния в рамках обновления значения.
Пример StackBlitz
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;
}
Ответ 7
В моем случае я объявил анимацию не на том компоненте по ошибке.
app.component.html
<app-order-details *ngIf="orderDetails" [@fadeInOut] [orderDetails]="orderDetails">
</app-order-details>
Анимация должна быть объявлена в компоненте, в котором используется элемент (appComponent.ts
). Вместо этого я объявил анимацию на OrderDetailsComponent.ts
.
Надеюсь, это поможет кому-то сделать ту же ошибку