diff --git a/src/state.js b/src/state.js index 8020876a6..9e5085f78 100644 --- a/src/state.js +++ b/src/state.js @@ -215,7 +215,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $ $state.transitionTo = function transitionTo(to, toParams, options) { if (!isDefined(options)) options = (options === true || options === false) ? { location: options } : {}; toParams = toParams || {}; - options = extend({ location: true, inherit: false, relative: null }, options); + options = extend({ location: true, inherit: false, relative: null, broadcastStateChangeSuccess : true }, options); var toState = findState(to, options.relative); @@ -274,6 +274,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $ var transition = $state.transition = resolved.then(function () { var l, entering, exiting; + if ($state.transition !== transition) return TransitionSuperseded; // Exit 'from' states not kept @@ -307,7 +308,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $ $location.url(toNav.url.format(toNav.locals.globals.$stateParams)); } - $rootScope.$broadcast('$stateChangeSuccess', to.self, toParams, from.self, fromParams); + if(options.broadcastStateChangeSuccess){ + $rootScope.$broadcast('$stateChangeSuccess', to.self, toParams, from.self, fromParams); + } + return $state.current; }, function (error) { diff --git a/test/stateSpec.js b/test/stateSpec.js index 02b180a96..cc76e6cc8 100644 --- a/test/stateSpec.js +++ b/test/stateSpec.js @@ -157,6 +157,32 @@ describe('state', function () { expect($state.current).toBe(D); })); + + it('does not trigger $stateChangeSuccess when flag prevents, but still transitions when different state', inject(function ($state, $q, $rootScope) { + initStateTo(E, { i: 'iii' }); + var called; + $rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) { + called = true; + }); + $state.transitionTo(D, { x: '1', y: '2' }, {broadcastStateChangeSuccess : false}); + $q.flush(); + expect(called).toBeFalsy(); + expect($state.current).toBe(D); + })); + + it('does not trigger $stateChangeSuccess when flag prevents, yet still updates params', inject(function ($state, $q, $rootScope) { + initStateTo(E, { x: 'iii' }); + var called; + $rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) { + called = true; + }); + $state.transitionTo(E, { i: '1', y: '2' }, {broadcastStateChangeSuccess : false}); + $q.flush(); + expect(called).toBeFalsy(); + expect($state.params.i).toBe('1'); + expect($state.current).toBe(E); + })); + it('is a no-op when passing the current state and identical parameters', inject(function ($state, $q) { initStateTo(A); var trans = $state.transitionTo(A, {}); // no-op