javascript - tom animation för komponent i ngFor
Jag har en lista med objekt och jag använder en egen komponent för att visa dem. Jag vill att dessa objekt ska animera in när de läggs till och animera ut när de tas bort. Att animera in verkar fungera bra, men när jag försöker animera ut dem försvinner de omedelbart. Jag tror att detta beror på att animations-egenskapen finns på ett element i komponenten, men det fungerar inte heller om jag lägger animations-egenskapen på komponentelementet.
animations = [
trigger('appear', [
state('void', style({ height: 0, opacity: 0.2 })),
transition('void => *', animate(200, style({ height: '*', opacity: 1 }))),
transition('* => void', animate(200)),
])
];
// Custom Component
@Component({
animations,
selector: 'bf-post',
template: `
<li style="overflow: hidden" [@appear] (click)="deleteItem.emit(item.id)">
{{item.text}}
</li>
`,
})
export class PostComponent {
@Input() item;
@Output() deleteItem = new EventEmitter;
}
// Using custom component, items is an array of the posts
<ul *ngIf="items.length" [class]="wallCss">
<bf-post *ngFor="let item of items" [item]="item"
(deleteItem)="deleteItem($event)"></bf-post>
</ul>
deleteItem(id) {
const idx = this.items.findIndex(item => id === item.id);
this.items = [
...this.items.slice(0, idx),
...this.items.slice(idx + 1),
];
}
li animerar korrekt varje gång ett objekt läggs till i items. Men när jag deleteItem för att ta bort ett av objekten, försvinner det omedelbart.
Jag har också försökt använda <bf-post [@appear], men detta animerar inte alls ... animationsstilarna måste förmodligen vara på li. Det verkar verkligen som om det väntar på att animationen ska slutföras innan elementet faktiskt tas bort ändå.
Finns det något sätt att korrekt animera ett elements tomma tillstånd som renderas inuti en ngFor?
Svar #1
Ingångs- och utgångsanimeringar har en bugg om du försöker koppla bort ett objekt med en metod.
(Komponenten kopplas faktiskt bort innan animationerna har en chans att köras).
Mer om buggen/problem som rapporterats på GitHub här
Du behöver använda host animation binding för att se animationen när komponenten lämnar.
Mer om Host Metadata-egenskapen för Component-dekoratören här
Därför behöver du ändra koden enligt nedan:
animations : [
trigger('appear', [
state('*', style({ height: 0, opacity: 0.2 })),
transition('void => *', animate(200, style({ height: '*', opacity: 1 }))),
transition('* => void', animate(200)),
])
];
// Custom Component
@Component({
animations,
selector: 'bf-post',
host: {
'[@appear]':'true'
}
template: `
<li style="overflow: hidden" (click)="deleteItem.emit(item.id)">
{{item.text}}
</li>
`,
})
export class PostComponent {
@Input() item;
@Output() deleteItem = new EventEmitter;
}
.........
Delar av koden har utelämnats för att undvika förvirring
- Observera ändringen av
[@appear]-bindningen i den anpassade mallen och tillägget av en ytterligarehost-metadataegenskap. - Du kan också behöva ändra
state-egenskapen i animationer till*istället förvoid1
1 Källhänvisning behövs | Osäker.
