【问题标题】:How to animate :enter & :leave transitions conditionally in Angular?如何在Angular中有条件地设置动画:进入和:离开过渡?
【发布时间】:2019-07-18 15:53:33
【问题描述】:

我有一个列表,其中的项目有这样的动画:

<li @animation>

这是我的动画触发器:

trigger('animation', [
  transition(':enter', [
    style({ height: '0px', 'padding-top': '0', 'padding-bottom': '0'}),  // initial
    animate('0.5s',
      style({ height: '*', 'padding-top': '*', 'padding-bottom': '*'}))  // final
  ]),
  transition(':leave', [
    style({ height: '*', 'padding-top': '*', 'padding-bottom': '*', opacity: 1}),  // initial
    animate('0.5s',
      style({ height: '0px', 'padding-top': '0', 'padding-bottom': '0', opacity: 0}))  // final
  ])
])

我如何有条件地为特定项目打开/关闭此动画?实际上我在寻找某事。像这样:

<li [@animation]=item.isAnimated>

这根本不起作用。

不幸的是,Angular 文档中只有一句话:

对于进入或离开页面的元素(从 DOM),您可以使动画有条件。例如,使用 *ngIf 使用 HTML 模板中的动画触发器。

但是当我将动画注释与 *ngIf 结合使用时,未动画的项目显然根本不会显示:

<li *ngIf="item.isAnimated" @animation>

无论 isAnimated 标志如何,我都想进一步显示所有项目。我只想打开/关闭特定项目的动画。

【问题讨论】:

    标签: angular angular-animations


    【解决方案1】:

    澄清一下: Angulars :enter:leave 关键字用于在 进入离开 dom。听起来很简单,但这正是您的方法和您试图实现的目标的问题。如果 dom 中有一个新元素,您希望它更加自定义,而不仅仅是动画,因此您需要自己的状态,这可以在列表条目的 ngOnInit 和 ngOnDestroy 中由您自己控制。

    方法可能如下:

    @Component({
      animations: [
        trigger('animation', [
          state('invisible', style({ height: '0px', 'padding-top': '0', 'padding-bottom': '0'}),
          state('visible', style({ height: '*', 'padding-top': '*', 'padding-bottom': '*'})
          transition('invisible => visible', animate('0.5s'))
          transition('visible => invisible', animate('0.5s'))
        ])
      ],
    })
    
    private readonly isAnimated: boolean = false/true //Where ever you get this value.
    public animationState: string //Or Enum with visible/invisible.
    
    public ngOnInit(): void {
      if (this.isAnimated) {
        animationState = 'visible'
      }
    }
    
    public ngOnDestroy(): void {
      if (this.isAnimated && this.animationState === 'visible') {
        animationState = 'invisible'
      }
    }
    
    <li [@animation]="animationState"/>
    

    如果对这种方法有任何疑问或问题,请告诉我,我们可以调整和讨论。

    【讨论】:

    • 这些项目没有自己的组件..这就是为什么我必须手动构建您使用 ngOnInit 和 ngOnDestroy 建议的逻辑.. 如果有人有任何其他想法,我想再等等这适用于我当前的代码。谢谢! ;)
    • 没问题 - 但是如果您需要单独的组件控件,它可能会有意义,而不是使用
    • 来为这个用例制作自己的小组件。不过,如果有一个开箱即用的角度解决方案,我也很感兴趣。 :)
    【解决方案2】:

    根据Angular IO

    当为 true 时,特殊的动画控件绑定 @.disabled 绑定会阻止所有动画的渲染。将 @.disabled 绑定放在元素上以禁用元素本身的动画,以及元素内的任何内部动画触发器。

    以下示例显示了如何使用此功能:

    @Component({
        selector: 'my-component',
        template: `
        <div [@.disabled]="isDisabled">
            <div [@childAnimation]="exp"></div>
        </div>
        `,
        animations: [
            trigger("childAnimation", [
                // ...
            ])
        ]
    })
    class MyComponent {
          isDisabled = true;
      exp = '...';
    }
    

    当@.disabled 为真时,它会阻止@childAnimation 触发器以及任何内部动画进行动画处理。

    【讨论】:

    • 解决这个特定问题的非常优雅的方式 - 我喜欢它。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签