Skip to content

Commit 291a70e

Browse files
committed
Added ability to queue child states and register them once their parent is registered.
1 parent 36321d3 commit 291a70e

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

src/state.js

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider', '$locationProvider'];
22
function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $locationProvider) {
33

4-
var root, states = {}, $state;
4+
var root, states = {}, $state, queue = {};
55

66
// Builds state properties from definition passed to registerState()
77
var stateBuilder = {
@@ -143,6 +143,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
143143
return undefined;
144144
}
145145

146+
function queueState(parentName, state) {
147+
if (!queue[parentName]) {
148+
queue[parentName] = [];
149+
}
150+
151+
queue[parentName].push(state);
152+
}
146153

147154
function registerState(state) {
148155
// Wrap a new object around the state so we can store our private details easily.
@@ -156,6 +163,17 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
156163
if (!isString(name) || name.indexOf('@') >= 0) throw new Error("State must have a valid name");
157164
if (states[name]) throw new Error("State '" + name + "'' is already defined");
158165

166+
// Get parent name
167+
var parentName =
168+
(name.indexOf('.') !== -1) ? name.substring(0, name.lastIndexOf('.'))
169+
: (isString(state.parent)) ? state.parent
170+
: '';
171+
172+
// If parent is not registered yet, add state to queue and register later
173+
if (parentName && !states[parentName]) {
174+
return queueState(parentName, state.self);
175+
}
176+
159177
for (var key in stateBuilder) {
160178
if (isFunction(stateBuilder[key])) state[key] = stateBuilder[key](state, stateBuilder.$delegates[key]);
161179
}
@@ -170,6 +188,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
170188
}]);
171189
}
172190

191+
// Register any queued children
192+
if (queue[name]) {
193+
for (var i = 0; i < queue[name].length; i++) {
194+
registerState(queue[name][i]);
195+
}
196+
}
197+
173198
return state;
174199
}
175200

test/stateSpec.js

+36-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('state', function () {
2525
E = { params: [ 'i' ] },
2626
H = { data: {propA: 'propA', propB: 'propB'} },
2727
HH = { parent: H },
28-
HHH = {parent: HH, data: {propA: 'overriddenA', propC: 'propC'} }
28+
HHH = {parent: HH, data: {propA: 'overriddenA', propC: 'propC'} },
2929
AppInjectable = {};
3030

3131
beforeEach(module(function ($stateProvider, $provide) {
@@ -87,7 +87,6 @@ describe('state', function () {
8787
expect($state.current).toBe(state);
8888
}
8989

90-
9190
describe('.transitionTo()', function () {
9291
it('returns a promise for the target state', inject(function ($state, $q) {
9392
var trans = $state.transitionTo(A, {});
@@ -716,3 +715,38 @@ describe('state', function () {
716715

717716
});
718717
});
718+
719+
describe('state queue', function(){
720+
angular.module('ui.router.queue.test', ['ui.router.queue.test.dependency'])
721+
.config(function($stateProvider) {
722+
$stateProvider
723+
.state('queue-test-a', {})
724+
.state('queue-test-b-child', { parent: 'queue-test-b' })
725+
.state('queue-test-b', {});
726+
});
727+
angular.module('ui.router.queue.test.dependency', [])
728+
.config(function($stateProvider) {
729+
$stateProvider
730+
.state('queue-test-a.child', {})
731+
});
732+
733+
var expectedStates = ['','queue-test-a', 'queue-test-a.child', 'queue-test-b', 'queue-test-b-child'];
734+
735+
it('should work across modules', function() {
736+
module('ui.router.queue.test', 'ui.router.queue.test.dependency');
737+
738+
inject(function ($state) {
739+
var list = $state.get().sort(function(a, b) { return (a.name > b.name) - (b.name > a.name); });
740+
expect(list.map(function(state) { return state.name; })).toEqual(expectedStates);
741+
});
742+
});
743+
744+
it('should work when parent is name string', function() {
745+
module('ui.router.queue.test', 'ui.router.queue.test.dependency');
746+
747+
inject(function ($state) {
748+
var list = $state.get().sort(function(a, b) { return (a.name > b.name) - (b.name > a.name); });
749+
expect(list.map(function(state) { return state.name; })).toEqual(expectedStates);
750+
});
751+
});
752+
});

0 commit comments

Comments
 (0)