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

Dev*_*con 12 animation angular angular-animations

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

<div *ngFor="let field of form.Fields">
    <div [ngSwitch]="field.Type" [@slideOut]>
        <!-- more field stuff -->
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

有了其他属性,我可以做这样的事情[attr.required]="field.Required"[attr.@slideOut]似乎没有用.

理想情况下,我想在我的场上有一个动画属性,所以我可以传递这样的动画,[@field.Animation]但我找不到任何关于如何做这样的事情的文档.有任何想法吗?

Mat*_*ers 15

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

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

<div *ngFor="let field of form.Fields">
    <div [@slideOut] [@.disabled]="!field.required">
        <!-- more field stuff -->
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

值得一提的是,在组件上使用 [@.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>
Run Code Online (Sandbox Code Playgroud)

动画片:

trigger('slideOut', [
    transition(':enter', [
        style({ opacity: '0' }),
        animate('{{duration}}ms cubic-bezier(0.4, 0.0, 0.2, 1)'),
        style({ opacity: '1' })
    ])
])
Run Code Online (Sandbox Code Playgroud)


use*_*534 12

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

在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})
          ]))
        ]
      )
    ])
  ]
})
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我一旦元素被实例化,就会让动画发生.在ngOnInit()方法中,我将this.watchMe设置为"fly"或"fade".

在html我附加了flyInOut触发器,如下所示:

<div [@flyInOut]="watchMe">
  Some content...
</div>
Run Code Online (Sandbox Code Playgroud)

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

这篇来自coursetro的文章也有很好的解释和视频.

  • 同意这是一个有点janky解决方案.但那是Angular,通常感觉你并没有真正开发只是配置其他人的代码. (4认同)
  • 我接受这作为答案,因为这是我发现这样做的唯一方法。我不喜欢管理动画状态,尤其是在这种情况下,因为我必须对数组中的每个项目都进行动画处理。我发现angular具有这两种动画形式(实例和状态)很奇怪。我也不喜欢角度小组无法动态添加的唯一属性:P Ohh (2认同)