如何在 Angular 2 中有条件地添加动画

Posted

技术标签:

【中文标题】如何在 Angular 2 中有条件地添加动画【英文标题】:How to conditionally add animations in Angular 2 【发布时间】:2017-09-11 00:34:27 【问题描述】:

我有一个包含字段的表单组件,当某些字段出现在表单中时我想对其进行动画处理,但不是每个字段。

<div *ngFor="let field of form.Fields">
    <div [ngSwitch]="field.Type" [@slideOut]>
        <!-- more field stuff -->
    </div>
</div>

使用其他属性我可以做这样的事情[attr.required]="field.Required"[attr.@slideOut] 似乎不起作用。

理想情况下,我希望在我的字段上拥有一个动画属性,这样我就可以传入像 [@field.Animation] 这样的动画,但我找不到任何关于我将如何做这样的事情的文档。有什么想法吗?

【问题讨论】:

slideOut 中的动画状态是什么?您应该使用类似 [@slideOut]="" 或类似的东西,其中 state_name 可以动态确定(例如,通过返回名称的方法)或静态(例如,只是硬编码的字符串) 我可以尝试类似的方法,现在 slideOut 是一个 void => * 动画。 然后从 set [@slideOut]="'test'" 或类似的开始 - 你的动画 def 中的 * 应该把它捡起来! 【参考方案1】:

我遇到了类似的问题,发现您需要采取稍微不同的方法。

在 Angular 中,动画与状态相关联。因此,与其在 html 中为动画定义不同的触发器,不如定义触发器可以在组件类中观察的多个状态。并且不是直接从方法触发动画,而是设置动画链接到的对象的状态。

例如,我可以在导入必要的模块后在组件装饰器中定义以下内容。

@Component(
  selector: 'app-some-animated',
  templateUrl: './some.component.html',
  styleUrls: ['./some-animated.component.scss'],
  animations: [
    trigger('flyInOut', [
      transition("void => fly", [
        animate(300, keyframes([
          style(transform: 'translateX(100%)', opacity: 0),
          style(transform: 'translateX(0)', opacity: 1)
        ]))
        ]
      )
    ]),
    trigger('flyInOut', [
      transition("void => fade", [
          animate(300, keyframes([
            style(opacity: 0),
            style(opacity: 1)
          ]))
        ]
      )
    ])
  ]
)

在这种情况下,我会在元素实例化后立即制作动画。在 ngOnInit() 方法中,我将 this.watchMe 设置为“fly”或“fade”。

在 html 中,我像这样附加 flyInOut 触发器:

<div [@flyInOut]="watchMe">
  Some content...
</div>

在您的情况下,您可能希望将所需状态添加到您的字段对象或作为*ngFor 的可迭代条件。

来自 coursetro 的This article 有一个很好的解释和一个视频。

【讨论】:

我接受这个作为答案,因为这是我发现的唯一方法。我不喜欢必须管理动画状态,尤其是在这种情况下,因为我必须为数组中的每个项目执行此操作。我觉得 Angular 有这两种形式的动画(实例和状态)很奇怪。我也不喜欢我无法动态添加的唯一属性是由 Angular 团队制作的:P Ohh well 同意这是一个有点笨拙的解决方案。但这就是 Angular,通常感觉你不是在真正开发,只是在配置别人的代码。 能否添加一个改变watchme状态的组件函数示例? 感谢您的回答。只是一个说明:我们需要使用变量(例如,如果我们使用 [@flyInOut]="'fly'" 它不会像我们预期的那样工作)【参考方案2】:

要有条件地启用或禁用动画触发器,请使用 https://angular.io/api/animations/trigger#disabling-animations 中记录的 [@.disabled]

以 OP 中的示例为例,如果每个字段都有一个带有布尔值的“必需”属性,并且动画应该只在这种情况下应用,那么代码可能是:

<div *ngFor="let field of form.Fields">
    <div [@slideOut] [@.disabled]="!field.required">
        <!-- more field stuff -->
    </div>
</div>

值得一提的是,在组件上使用 [@.disabled] 也会禁用任何子组件上的动画,例如材质菜单的外观将不再具有动画效果。

在必要时,可以通过使用条件将父动画上的动画持续时间设置为 0 来避免这种情况,这会(视觉上)移除动画,而不会影响任何子组件。

模板:

<div *ngFor="let field of form.Fields">
    <div [@slideOut]="field.required ? value:'', params:duration : 200 : value:'', params:duration : 0">
        <!-- more field stuff -->
    </div>
</div>

动画:

trigger('slideOut', [
    transition(':enter', [
        style( opacity: '0' ),
        animate('durationms cubic-bezier(0.4, 0.0, 0.2, 1)'),
        style( opacity: '1' )
    ])
])

【讨论】:

以上是关于如何在 Angular 2 中有条件地添加动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在Angular中有条件地用不同的div包装元素

Angular 2 有条件地添加属性指令

如何在 Svelte 中有条件地禁用字段?

如何在 Vue 中有条件地添加一个类?

如何在 Svelte 3 中有条件地添加和删除`use:`属性?

如何在反应中有条件地添加样式? [复制]