From a5578de7e80aac62b21967d4e949ec72c34823fc Mon Sep 17 00:00:00 2001 From: Chris Thielen Date: Tue, 1 Mar 2016 08:21:26 -0600 Subject: [PATCH] feat(uiView): Put $animate promises on element.data('$uiView') closes #2562 closes #2579 --- src/ng1/viewDirective.ts | 19 +++++++++++----- test/viewDirectiveSpec.js | 46 ++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/ng1/viewDirective.ts b/src/ng1/viewDirective.ts index c50e70bfe..4c785488c 100644 --- a/src/ng1/viewDirective.ts +++ b/src/ng1/viewDirective.ts @@ -196,20 +196,22 @@ function $ViewDirective( $view, $animate, $uiViewScroll, $interpolate, function cleanupLastView() { if (previousEl) { - trace.traceUiViewEvent("Removing (previous) el", viewData); + trace.traceUiViewEvent("Removing (previous) el", previousEl.data('$uiView')); previousEl.remove(); previousEl = null; } if (currentScope) { - trace.traceUiViewEvent("Destroying (previous) scope", viewData); + trace.traceUiViewEvent("Destroying scope", viewData); currentScope.$destroy(); currentScope = null; } if (currentEl) { - trace.traceUiViewEvent("Animate out (previous)", viewData); + let _viewData = currentEl.data('$uiView'); + trace.traceUiViewEvent("Animate out", _viewData); renderer.leave(currentEl, function() { + _viewData.$$animLeave.resolve(); previousEl = null; }); @@ -222,17 +224,22 @@ function $ViewDirective( $view, $animate, $uiViewScroll, $interpolate, config = config || {}; let newScope = scope.$new(); trace.traceUiViewScopeCreated(viewData, newScope); + let animEnter = $q.defer(), animLeave = $q.defer(); - extend(viewData, { + let $uiViewData = extend({}, viewData, { context: config.context, $template: config.template, $controller: config.controller, $controllerAs: config.controllerAs, - $locals: config.locals + $locals: config.locals, + $animEnter: animEnter.promise, + $animLeave: animLeave.promise, + $$animLeave: animLeave }); let cloned = $transclude(newScope, function(clone) { - renderer.enter(clone.data('$uiView', viewData), $element, function onUiViewEnter() { + renderer.enter(clone.data('$uiView', $uiViewData), $element, function onUiViewEnter() { + animEnter.resolve(); if (currentScope) { currentScope.$emit('$viewContentAnimationEnded'); } diff --git a/test/viewDirectiveSpec.js b/test/viewDirectiveSpec.js index b55a9b0f9..4ea19818e 100644 --- a/test/viewDirectiveSpec.js +++ b/test/viewDirectiveSpec.js @@ -6,18 +6,14 @@ function animateFlush($animate) { $animate && $animate.flush && $animate.flush(); // 1.4 } -function animateFlush($animate) { - $animate && $animate.triggerCallbacks && $animate.triggerCallbacks(); // 1.2-1.3 - $animate && $animate.flush && $animate.flush(); // 1.4 -} - describe('uiView', function () { 'use strict'; - var scope, $compile, elem; + var scope, $compile, elem, log; beforeEach(function() { var depends = ['ui.router']; + log = ""; try { angular.module('ngAnimate'); @@ -113,6 +109,15 @@ describe('uiView', function () { controller: function ($scope, $element) { $scope.elementId = $element.attr('id'); } + }, + nState = { + template: 'nState', + controller: function ($scope, $element) { + var data = $element.data('$uiView'); + $scope.$on("$destroy", function() { log += 'destroy;'}); + data.$animEnter.then(function() { log += "animEnter;"}); + data.$animLeave.then(function() { log += "animLeave;"}); + } }; beforeEach(module(function ($stateProvider) { @@ -130,6 +135,7 @@ describe('uiView', function () { .state('k', kState) .state('l', lState) .state('m', mState) + .state('n', nState) })); beforeEach(inject(function ($rootScope, _$compile_) { @@ -578,6 +584,34 @@ describe('uiView', function () { // No more animations expect($animate.queue.length).toBe(0); })); + + it ('should expose animation promises to controllers', inject(function($state, $q, $compile, $animate, $transitions) { + $transitions.onStart({}, function($transition$) { log += 'start:' + $transition$.to().name + ';'; }); + $transitions.onFinish({}, function($transition$) { log += 'finish:' + $transition$.to().name + ';'; }); + $transitions.onSuccess({}, function($transition$) { log += 'success:' + $transition$.to().name + ';'; }); + + var content = 'Initial Content'; + elem.append($compile('
' + content + '
')(scope)); + $state.transitionTo('n'); + $q.flush(); + + expect($state.current.name).toBe('n'); + expect(log).toBe('start:n;finish:n;success:n;'); + + animateFlush($animate); + $q.flush(); + expect(log).toBe('start:n;finish:n;success:n;animEnter;'); + + $state.transitionTo('a'); + $q.flush(); + expect($state.current.name).toBe('a'); + expect(log).toBe('start:n;finish:n;success:n;animEnter;start:a;finish:a;destroy;success:a;'); + + animateFlush($animate); + $q.flush(); + expect(log).toBe('start:n;finish:n;success:n;animEnter;start:a;finish:a;destroy;success:a;animLeave;'); + })); + }); });