5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AngularJSAdvent Calendar 2015

Day 7

ng-animate-swap - AngularJS v1.5

Last updated at Posted at 2015-12-06

AngularJS Advent Calendar 2015 7日目の投稿です。
v1.5 で追加された ng-animate-swap についてです。

ng-animate-swap

ng-animate-swap は v1.5 で新たに追加された directive で、特定のブロックの内容を、アニメーションで切り替えるための directive です。紹介されていたサンプルでもそうですが、要はローテーションバナーのような動きを実現するためのものです。
アニメーションというだけあって、ngAnimate の読み込みが必要になります。

サンプルを見てみる

Plunker にあるよとのことなので、見てみます。API Docにもあったので残しておきます。

使用方法は以下の通りです。

<div class="banner-container">
  <img ng-src="{{ currentBannerImage }}"
       class=”animate-banner”
       ng-animate-swap="currentBannerImage" />
</div>

ng-animate-swap="currentBannerImage" と追加するとその要素が対象になります。
このサンプルだと currentBannerImage の値を監視し続けて、値(画像パスが)が変わった場合のみ ng-animate-swap によるコンテンツ(画像)の差し替え処理がおこなわれます。特に画像に限るわけではないので、特定のコンテンツにアニメーションをつけて切り替えたい場合などで利用できます。

<div class="container">
  <div class="xxx" ng-animate-swap="myModel">
    コンテンツ
  </div>
</div>

とかでもOK。

通常この手のものを作る時は先に全ての DOM をレンダリングさせてから表示切り替えをやったりしますが、上記をみるとタグ1つで簡潔に記述できるのが良いところ。実際は、アニメーションの開始時に DOM の挿入、アニメーション終了時に DOM の削除をおこなっています。この辺は ngAnimate の機能がやってくれています。

ソースを見てみる

ngAnimateSwap.js にありました。

var ngAnimateSwapDirective = ['$animate', '$rootScope', function($animate, $rootScope) {
  return {
    restrict: 'A',
    transclude: 'element',
    terminal: true,
    priority: 600, // we use 600 here to ensure that the directive is caught before others
    link: function(scope, $element, attrs, ctrl, $transclude) {
      var previousElement, previousScope;
      scope.$watchCollection(attrs.ngAnimateSwap || attrs['for'], function(value) {
        if (previousElement) {
          $animate.leave(previousElement);
        }
        if (previousScope) {
          previousScope.$destroy();
          previousScope = null;
        }
        if (value || value === 0) {
          previousScope = scope.$new();
          $transclude(previousScope, function(element) {
            previousElement = element;
            $animate.enter(element, null, $element);
          });
        }
      });
    }
  };
}];

$transclude で新しい template として扱われて DOM に追加するようになってますね。

あと、しれっと for$watchCollection で監視対象になってます。
なので、以下のように for="xxx" と指定しても動きます。

<div class="banner-container">
  <img ng-src="{{ currentBannerImage }}"
       class=”animate-banner”
       ng-animate-swap for="currentBannerImage" />
</div>

まとめ

限定的な用途になりそうではあるけれども、知らずに自作するよりははるかに簡単です。
見た目も見やすいですしね(若干の黒魔法感は否めません)

参考

http://angularjs.blogspot.jp/2015/11/angularjs-15-beta2-and-14-releases.html
http://plnkr.co/edit/xAuvOc7lkNvs0TsUiysj?p=preview
https://docs.angularjs.org/api/ngAnimate/directive/ngAnimateSwap

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?