diff --git a/src/state.js b/src/state.js index cd55fa80a..ce7f49f43 100644 --- a/src/state.js +++ b/src/state.js @@ -336,8 +336,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $ // But clear 'transition', as we still want to cancel any other pending transitions. // TODO: We may not want to bump 'transition' if we're called from a location change that we've initiated ourselves, // because we might accidentally abort a legitimate transition initiated from code? - if (to === from && locals === from.locals && !options.reload) { - syncUrl(); + if (shouldTriggerReload(to, from, locals, options) ) { + if ( to.self.reloadOnSearch !== false ) + syncUrl(); $state.transition = null; return $q.when($state.current); } @@ -577,6 +578,12 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $ }); return filtered; } + + function shouldTriggerReload(to, from, locals, options) { + if ( to === from && ((locals === from.locals && !options.reload) || (to.self.reloadOnSearch === false)) ) { + return true; + } + } } angular.module('ui.router.state') diff --git a/test/stateSpec.js b/test/stateSpec.js index deac94f79..201a8c969 100644 --- a/test/stateSpec.js +++ b/test/stateSpec.js @@ -26,6 +26,7 @@ describe('state', function () { H = { data: {propA: 'propA', propB: 'propB'} }, HH = { parent: H }, HHH = {parent: HH, data: {propA: 'overriddenA', propC: 'propC'} }, + RS = { url: '^/search?term', reloadOnSearch: false }, AppInjectable = {}; beforeEach(module(function ($stateProvider, $provide) { @@ -45,6 +46,7 @@ describe('state', function () { .state('H', H) .state('HH', HH) .state('HHH', HHH) + .state('RS', RS) .state('home', { url: "/" }) .state('home.item', { url: "front/:id" }) @@ -141,6 +143,18 @@ describe('state', function () { expect($state.current).toBe(A); })); + it('doesn\'t trigger state change if reloadOnSearch is false', inject(function ($state, $q, $location, $rootScope){ + initStateTo(RS); + $location.search({term: 'hello'}); + var called; + $rootScope.$on('$stateChangeStart', function (ev, to, toParams, from, fromParams) { + called = true + }); + $q.flush(); + expect($location.search()).toEqual({term: 'hello'}); + expect(called).toBeFalsy(); + })); + it('ignores non-applicable state parameters', inject(function ($state, $q) { $state.transitionTo('A', { w00t: 'hi mom!' }); $q.flush(); @@ -641,6 +655,7 @@ describe('state', function () { 'H', 'HH', 'HHH', + 'RS', 'about', 'about.person', 'about.person.item', @@ -899,4 +914,4 @@ describe('state queue', function(){ expect(list.map(function(state) { return state.name; })).toEqual(expectedStates); }); }); -}); \ No newline at end of file +});