0

我们有一个非常简单的组件,应该淡入淡出:enter:leave事件:

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

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss'],
  animations: [
    trigger('host', [
      transition(':enter', [
        style({ opacity: 0 }),
        animate('240ms linear', style({ opacity: 1 })),
      ]),
      transition(':leave', [
        style({ opacity: 1 }),
        animate('240ms linear', style({ opacity: 0 })),
      ])
    ]),
  ]
})

export class TestComponent {
  @HostBinding('@host') host() {
    return true;
  }
}

该组件的使用方式如下:

<app-test *ngIf="someBoolean"></app-test>

现在动画:enter确实运行了。但是当组件被移除时,元素不会淡出(变量someBoolean变为false)。

什么不见​​了?

4

2 回答 2

1

在父组件中使用*ngIf使元素动画不被注册

让我们看看会发生什么

  • someBoolean=> 从false
  • <app-test *ngIf='someBoolean'></app-test>不存在
  • someBoolean=>true
  • 加载<app-test></app-test>
  • 加载动画;……等一下,刚刚发生了什么?我们加载app-test然后加载动画!但是在什么时候触发动画呢?这个问题的答案是为什么你的动画没有被触发。我们需要先申请动画,然后才能应用它们

所以让我们停止上述事件序列并重试这些步骤

  • someBoolean=> 从false
  • <app-test [shown]='someBoolean'></app-test>创建
  • 注册动画
  • someBoolean=>true
  • 显示内容<app-test></app-test>
  • 动画在他们注册后开始!

好的,现在我们已经了解了它的工作原理,让我们开始编写代码

组件使用

`<app-test [shown]='someBoolean'></app-test>`

组件 TS 文件

@Component({
  selector: "app-test",
  templateUrl: "./test.component.html",
  styleUrls: ["./test.component.css"],
  animations: [
    trigger("host", [
      transition(":enter", [
        style({ opacity: 0 }),
        animate("240ms linear", style({ opacity: 1 }))
      ]),
      transition(":leave", [
        style({ opacity: 1 }),
        animate("240ms linear", style({ opacity: 0 }))
      ])
    ])
  ]
})
export class TestComponent implements OnInit {
  // @HostBinding("@host") host() {
  //   return true;
  // }
  @Input() shown;

  constructor() {}

  ngOnInit() {}
}

我已经注释掉了,@HostBinding因为我没有看到它是如何在这里实现的。

最后我们可以*ngIf在组件的内容中应用

<div *ngIf='shown'>
  <!-- Animation works! -->
</div>

在此处查看演示

于 2021-05-03T11:17:34.320 回答
0

这能解决问题吗?

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

@Component({
  selector: 'parent',
  animations: [
    trigger('toggle', [
      state('true', style({ overflow: 'hidden', opacity: '*' })),
      state('false', style({ overflow: 'hidden', opacity: 0, height: 0 })),
      transition('true => false', animate('400ms ease-in-out')),
      transition('false => true', animate('400ms ease-in-out')),
    ]),
  ],
  template: `
    <button (click)="someBoolean = !someBoolean">CLICK</button>
    <div [@toggle]="someBoolean">
      <app-test></app-test>
    </div>
  `,
})
export class ParentComponent {
  someBoolean = false;
}
于 2021-05-09T19:27:52.200 回答