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