从 ngFor 中删除元素时,如何在 Angular 7 中使用退出动画?

How do I utilize an exit animation in Angular 7 when removing an element from ngFor?

我正在尝试从 Observable 数组中删除一个元素并使用退出动画。进入动画效果很好,但是退出动画根本不会触发,元素会突然被删除。我在下面包含了我的代码。感谢任何帮助或建议!

ao-notifications.service.ts

import { Injectable } from '@angular/core';
import { Observable, BehaviorSubject, timer } from 'rxjs';
import * as _ from 'lodash';

import Message from '../dependencies/Message';
import MessageOptions from '../dependencies/MessageOptions';

@Injectable({
  providedIn: 'root'
})
export class AoNotificationsService {
  id: BehaviorSubject<number> = new BehaviorSubject<number>(0);
  messages: BehaviorSubject<Message[]> = new BehaviorSubject<Message[]>([]);

  list(): Observable<Message[]> {
    return this.messages;
  }

  emit({ content, style, delay }: MessageOptions) {
    const id = this.id.getValue();
    const message = new Message(id, content, style);

    this.messages.next(_.sortBy(_.concat(this.messages.getValue(), message), (o: Message) => o.id).reverse());

    if (delay) {
      timer(delay).subscribe(() => this.purge(id));
    }

    this.id.next(id + 1);
  }

  purge(id: number) {
    this.messages.next(_.filter(this.messages.getValue(), o => o.id !== id));
  }
}

ao-notifications.component.html

<div class="wrapper">
  <aside *ngFor="let message of (messages | async)">
    <div
      @messageState
      class="notification"
      [ngClass]="{
        primary: message.style == 'primary',
        secondary: message.style == 'secondary',
        success: message.style == 'success',
        danger: message.style == 'danger',
        warning: message.style == 'warning',
        info: message.style == 'info'
      }"
    >
      <button class="dismiss" (click)="dismiss(message.id)">X</button> {{ message.content }}
    </div>
  </aside>
</div>

ao-notifications.component.ts

import { Component, OnInit } from '@angular/core';
import { trigger, style, animate, transition } from '@angular/animations';
import { Observable } from 'rxjs';

import Message from './dependencies/Message';

import { AoNotificationsService } from './services/ao-notifications.service';

@Component({
  selector: 'ao-notifications',
  templateUrl: './ao-notifications.component.html',
  styleUrls: ['./ao-notifications.component.scss'],
  animations: [
    trigger('messageState', [
      transition('void => *', [
        style({
          opacity: 0
        }),
        animate(
          '1s ease-in-out',
          style({
            opacity: 1
          })
        )
      ]),
      transition('* => void', [
        animate(
          '1s ease-in-out',
          style({
            opacity: 0
          })
        )
      ])
    ])
  ]
})
export class AoNotificationsComponent implements OnInit {
  messages: Observable<Message[]>;

  constructor(private notifications: AoNotificationsService) {}

  ngOnInit() {
    this.messages = this.notifications.list();
  }

  dismiss(id: number) {
    this.notifications.purge(id);
  }
}

问题是因为 *ngFor 在旁边,而不是在调用 @messageState 的 div 上。如果像下面这样修改,动画就可以正常工作了。

<div class="wrapper">
  <aside>
    <div
      *ngFor="let message of (messages | async)" <!-- Fixed Here -->
      @messageState
      class="notification"
      [ngClass]="{
        primary: message.style == 'primary',
        secondary: message.style == 'secondary',
        success: message.style == 'success',
        danger: message.style == 'danger',
        warning: message.style == 'warning',
        info: message.style == 'info'
      }"
    >
      <button class="dismiss" (click)="dismiss(message.id)">X</button> {{ message.content }}
    </div>
  </aside>
</div>