Skip to content

Commit 91c1ff1

Browse files
cherry-pick e00aa69 from 0.2.17; also re-implement global variable $state.transition for backwards compat.
1 parent affd29d commit 91c1ff1

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

src/ng1/stateEvents.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import {Transition} from "../transition/transition";
2828
return memo;
2929
}
3030

31-
stateChangeStartHandler.$inject = ['$transition$', '$stateEvents', '$rootScope', '$urlRouter'];
32-
function stateChangeStartHandler($transition$: Transition, $stateEvents, $rootScope, $urlRouter) {
31+
stateChangeStartHandler.$inject = ['$transition$', '$stateEvents', '$rootScope', '$state', '$urlRouter'];
32+
function stateChangeStartHandler($transition$: Transition, $stateEvents, $rootScope, $state, $urlRouter) {
3333
if (!$transition$.options().notify || !$transition$.valid() || $transition$.ignored())
3434
return;
3535

@@ -70,7 +70,8 @@ import {Transition} from "../transition/transition";
7070
if (enabledEvents.$stateChangeCancel) {
7171
$rootScope.$broadcast('$stateChangeCancel', $transition$.to(), toParams, $transition$.from(), fromParams, $transition$);
7272
}
73-
$urlRouter.update();
73+
//Don't update and resync url if there's been a new transition started. see issue #2238, #600
74+
if ($state.transition == null) $urlRouter.update();
7475
return false;
7576
}
7677

src/state/hooks/transitionManager.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,16 @@ export class TransitionManager {
6464
runTransition(): IPromise<any> {
6565
this.activeTransQ.clear(); // TODO: nuke this
6666
this.activeTransQ.enqueue(this.transition);
67+
this.$state.transition = this.transition;
6768
let promise = this.transition.run()
6869
.then((trans: Transition) => trans.to()) // resolve to the final state (TODO: good? bad?)
6970
.catch(error => this.transRejected(error)); // if rejected, handle dynamic and redirect
7071

71-
let always = () => this.activeTransQ.remove(this.transition);
72+
let always = () => {
73+
this.activeTransQ.remove(this.transition);
74+
if (this.$state.transition === this.transition) this.transition = null;
75+
};
76+
7277
promise.then(always, always);
7378

7479
return promise;

test/stateSpec.js

+32
Original file line numberDiff line numberDiff line change
@@ -1994,3 +1994,35 @@ describe('$stateParams', function () {
19941994
expect($stateParams.foo).toBeUndefined();
19951995
}));
19961996
});
1997+
1998+
// Test for #600, #2238, #2229
1999+
describe('otherwise and state redirects', function() {
2000+
beforeEach(module('ui.router.state.events', function($stateEventsProvider) {
2001+
$stateEventsProvider.enable();
2002+
}));
2003+
2004+
beforeEach(module(function ($stateProvider, $urlRouterProvider) {
2005+
$urlRouterProvider.otherwise('/home');
2006+
$stateProvider
2007+
.state('home', { url: '/home', template: 'home' })
2008+
.state('loginPage', { url: '/login', templateUrl: 'login.html' });
2009+
}));
2010+
2011+
beforeEach(inject(function ($rootScope, $state) {
2012+
$rootScope.$on('$stateChangeStart', function (event, toState) {
2013+
if (toState.name !== "loginPage") {
2014+
event.preventDefault();
2015+
$state.go('loginPage', { redirectUrl: toState.name });
2016+
}
2017+
});
2018+
}));
2019+
2020+
it("should not go into an infinite loop", inject(function($location, $rootScope, $state, $urlRouter, $httpBackend) {
2021+
$httpBackend.expectGET("login.html").respond("login page");
2022+
$location.url("notmatched");
2023+
$urlRouter.update(true);
2024+
expect(function() { $rootScope.$digest(); }).not.toThrow();
2025+
expect(function() { $httpBackend.flush(); }).not.toThrow();
2026+
expect($state.current.name).toBe("loginPage")
2027+
}));
2028+
});

0 commit comments

Comments
 (0)