diff --git a/src/state.js b/src/state.js index be36c99bc..9a2034691 100644 --- a/src/state.js +++ b/src/state.js @@ -696,9 +696,12 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { * @requires $injector * @requires ui.router.util.$resolve * @requires ui.router.state.$stateParams + * @requires ui.router.state.$stateSearch * @requires ui.router.router.$urlRouter * - * @property {object} params A param object, e.g. {sectionId: section.id)}, that + * @property {object} params A param object, e.g. {sectionId: section.id}, that + * you'd like to test against the current active state. + * @property {object} search A $location.search copy, e.g. {myarg: 123}, that * you'd like to test against the current active state. * @property {object} current A reference to the state's config object. However * you passed it in. Useful for accessing custom data. @@ -711,8 +714,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { * you're coming from. */ this.$get = $get; - $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter', '$location', '$urlMatcherFactory']; - function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $urlRouter, $location, $urlMatcherFactory) { + $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$stateSearch', '$urlRouter', '$location', '$urlMatcherFactory']; + function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $stateSearch, $urlRouter, $location, $urlMatcherFactory) { var TransitionSuperseded = $q.reject(new Error('transition superseded')); var TransitionPrevented = $q.reject(new Error('transition prevented')); @@ -788,6 +791,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { $state = { params: {}, + search: {}, current: root.self, $current: root, transition: null @@ -1042,6 +1046,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { }); $urlRouter.update(true); } + var toSearch = angular.extend({}, $location.search()); + $state.search = toSearch; + copy($state.search, $stateSearch); + $state.transition = null; return $q.when($state.current); } @@ -1145,6 +1153,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { }); } + var toSearch = angular.extend({}, $location.search()); + $state.search = toSearch; + copy($state.search, $stateSearch); + if (options.notify) { /** * @ngdoc event @@ -1463,4 +1475,5 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { angular.module('ui.router.state') .factory('$stateParams', function () { return {}; }) + .factory('$stateSearch', function () { return {}; }) .provider('$state', $StateProvider); diff --git a/test/stateSpec.js b/test/stateSpec.js index cecde231c..f108291f6 100644 --- a/test/stateSpec.js +++ b/test/stateSpec.js @@ -233,7 +233,21 @@ describe('state', function () { expect(called).toBeFalsy(); })); - it('updates URL when changing only query params via $state.go() when reloadOnSearch=false', inject(function ($state, $stateParams, $q, $location, $rootScope){ + it('updates $stateSearch when state.reloadOnSearch=false', inject(function ($state, $stateParams, $stateSearch, $q, $location, $rootScope){ + initStateTo(RS); + $location.search({term: 'hello', myarg: 'search'}); + var called; + $rootScope.$on('$stateChangeStart', function (ev, to, toParams, from, fromParams, options) { + called = true + }); + $q.flush(); + expect($stateParams).toEqual({term: 'hello'}); + expect($state.search).toEqual({term: 'hello', myarg: 'search'}); + expect($stateSearch).toEqual({term: 'hello', myarg: 'search'}); + expect(called).toBeFalsy(); + })); + + it('updates URL when changing only query params via $state.go() when reloadOnSearch=false', inject(function ($state, $stateParams, $stateSearch, $q, $location, $rootScope){ initStateTo(RS); var called; $state.go(".", { term: 'goodbye' }); @@ -242,6 +256,8 @@ describe('state', function () { }); $q.flush(); expect($stateParams).toEqual({term: 'goodbye'}); + expect($state.search).toEqual({term: 'goodbye'}); + expect($stateSearch).toEqual({term: 'goodbye'}); expect($location.url()).toEqual("/search?term=goodbye"); expect(called).toBeFalsy(); })); @@ -605,7 +621,7 @@ describe('state', function () { expect($state.$current.name).toBe('about.sidebar'); })); - it('keeps parameters from common ancestor states', inject(function ($state, $stateParams, $q) { + it('keeps parameters from common ancestor states', inject(function ($state, $stateParams, $stateSearch, $q) { $state.transitionTo('about.person', { person: 'bob' }); $q.flush(); @@ -614,6 +630,7 @@ describe('state', function () { expect($state.$current.name).toBe('about.person.item'); expect($stateParams).toEqual({ person: 'bob', id: "5" }); + expect($stateSearch).toEqual({}); $state.go('^.^.sidebar'); $q.flush();