web-dev-qa-db-ja.com

Angular 2に条件付きでアニメーションを追加する方法

フィールドを持つフォームコンポーネントがあります。フォームに表示されたときにアニメーション化したいフィールドもありますが、すべてのフィールドではありません。

<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]しかし、このようなことをどのように行うかについてのドキュメントは見つかりません。何か案は?

14
Devcon

私は同様の問題に直面し、少し異なるアプローチをとる必要があることに気付きました。

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からの反復可能な条件として追加する必要があります。

この記事 コーストロからの素晴らしい説明とビデオもあります。

12
user2528534

アニメーショントリガーを条件付きで有効または無効にするには、 https://angular.io/api/animations/trigger#disabling-animations に記載されている[@ .disabled]を使用します

OPの例では、各フィールドにブール値の「必須」プロパティがあり、これがtrueの場合にのみアニメーションを適用する必要がある場合、コードは次のようになります。

<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('{{duration}}ms cubic-bezier(0.4, 0.0, 0.2, 1)'),
        style({ opacity: '1' })
    ])
])
2
Matt Saunders