Skip to content

Commit

Permalink
fix(viewDirective): $destroy event is triggered before animation ends
Browse files Browse the repository at this point in the history
when view is animated using ngAnimate, $destroy event is triggered before
animation ends.

closes #1643
  • Loading branch information
Teemu Kokkonen committed Oct 30, 2015
1 parent d23e9fa commit 1be1379
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
29 changes: 21 additions & 8 deletions src/viewDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,32 +190,45 @@ function $ViewDirective( $state, $injector, $uiViewScroll, $interpolate)
updateView(true);

function cleanupLastView() {
if (previousEl) {
previousEl.remove();
previousEl = null;
var _previousEl = previousEl;
var _currentScope = currentScope;

if (_currentScope) {
_currentScope._willBeDestroyed = true;

This comment has been minimized.

Copy link
@xtianus79

xtianus79 Feb 1, 2016

Is this true resetting? Or should it just be destroy if in the current scope?

This comment has been minimized.

Copy link
@nateabele

nateabele Feb 1, 2016

Contributor

This is for views that have an exit transition animation. They cannot be destroyed until the animation completes, or else the view is corrupted.

This comment has been minimized.

Copy link
@xtianus79

xtianus79 Feb 2, 2016

i must have an issue with my animation completing...

}

if (currentScope) {
currentScope.$destroy();
currentScope = null;
function cleanOld() {
if (_previousEl) {
_previousEl.remove();
}

if (_currentScope) {
_currentScope.$destroy();
}
}

if (currentEl) {
renderer.leave(currentEl, function() {
cleanOld();

This comment has been minimized.

Copy link
@christopherthielen

christopherthielen Feb 1, 2016

Contributor

after animation completes, cleanOld is called, which calls _currentScope.$destroy()

previousEl = null;
});

previousEl = currentEl;
currentEl = null;
} else {
cleanOld();
previousEl = null;
}

currentEl = null;
currentScope = null;
}

function updateView(firstTime) {
var newScope,
name = getUiViewName(scope, attrs, $element, $interpolate),
previousLocals = name && $state.$current && $state.$current.locals[name];

if (!firstTime && previousLocals === latestLocals) return; // nothing to do
if (!firstTime && previousLocals === latestLocals || scope._willBeDestroyed) return; // nothing to do
newScope = scope.$new();
latestLocals = $state.$current.locals[name];

Expand Down
36 changes: 35 additions & 1 deletion test/viewDirectiveSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
describe('uiView', function () {
'use strict';

var scope, $compile, elem;
var log, scope, $compile, elem;

beforeEach(function() {
var depends = ['ui.router'];
Expand All @@ -27,6 +27,10 @@ describe('uiView', function () {
});
}));

beforeEach(function() {
log = '';
});

var aState = {
template: 'aState template'
},
Expand Down Expand Up @@ -112,6 +116,19 @@ describe('uiView', function () {
.state('j', jState)
.state('k', kState)
.state('l', lState)
.state('m', {
controller: function($scope) {
log += 'm;';
$scope.$on('$destroy', function() {
log += '$destroy(m);';
});
},
})
.state('n', {
controller: function($scope) {
log += 'n;';
},
});
}));

beforeEach(inject(function ($rootScope, _$compile_) {
Expand All @@ -122,6 +139,23 @@ describe('uiView', function () {

describe('linking ui-directive', function () {

it('$destroy event is triggered after animation ends', inject(function($state, $q, $animate) {
elem.append($compile('<div><ui-view></ui-view></div>')(scope));

$state.transitionTo('m');
$q.flush();
expect(log).toBe('m;');
$state.transitionTo('n');
$q.flush();
if ($animate) {
expect(log).toBe('m;n;');
$animate.triggerCallbacks();
expect(log).toBe('m;n;$destroy(m);');
} else {
expect(log).toBe('m;$destroy(m);n;');
}
}));

it('anonymous ui-view should be replaced with the template of the current $state', inject(function ($state, $q) {
elem.append($compile('<div><ui-view></ui-view></div>')(scope));

Expand Down

0 comments on commit 1be1379

Please sign in to comment.