Skip to content

Commit

Permalink
Merge pull request #492 from theJoeBiz/master
Browse files Browse the repository at this point in the history
Added ability to queue up children and register them once their parent is registered
  • Loading branch information
nateabele committed Oct 14, 2013
2 parents 14ab5f4 + 291a70e commit 5cac9e7
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
27 changes: 26 additions & 1 deletion src/state.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider', '$locationProvider'];
function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $locationProvider) {

var root, states = {}, $state;
var root, states = {}, $state, queue = {};

// Builds state properties from definition passed to registerState()
var stateBuilder = {
Expand Down Expand Up @@ -143,6 +143,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
return undefined;
}

function queueState(parentName, state) {
if (!queue[parentName]) {
queue[parentName] = [];
}

queue[parentName].push(state);
}

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

// Get parent name
var parentName =
(name.indexOf('.') !== -1) ? name.substring(0, name.lastIndexOf('.'))
: (isString(state.parent)) ? state.parent
: '';

// If parent is not registered yet, add state to queue and register later
if (parentName && !states[parentName]) {
return queueState(parentName, state.self);
}

for (var key in stateBuilder) {
if (isFunction(stateBuilder[key])) state[key] = stateBuilder[key](state, stateBuilder.$delegates[key]);
}
Expand All @@ -170,6 +188,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
}]);
}

// Register any queued children
if (queue[name]) {
for (var i = 0; i < queue[name].length; i++) {
registerState(queue[name][i]);
}
}

return state;
}

Expand Down
38 changes: 36 additions & 2 deletions test/stateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('state', function () {
E = { params: [ 'i' ] },
H = { data: {propA: 'propA', propB: 'propB'} },
HH = { parent: H },
HHH = {parent: HH, data: {propA: 'overriddenA', propC: 'propC'} }
HHH = {parent: HH, data: {propA: 'overriddenA', propC: 'propC'} },
AppInjectable = {};

beforeEach(module(function ($stateProvider, $provide) {
Expand Down Expand Up @@ -87,7 +87,6 @@ describe('state', function () {
expect($state.current).toBe(state);
}


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

});
});

describe('state queue', function(){
angular.module('ui.router.queue.test', ['ui.router.queue.test.dependency'])
.config(function($stateProvider) {
$stateProvider
.state('queue-test-a', {})
.state('queue-test-b-child', { parent: 'queue-test-b' })
.state('queue-test-b', {});
});
angular.module('ui.router.queue.test.dependency', [])
.config(function($stateProvider) {
$stateProvider
.state('queue-test-a.child', {})
});

var expectedStates = ['','queue-test-a', 'queue-test-a.child', 'queue-test-b', 'queue-test-b-child'];

it('should work across modules', function() {
module('ui.router.queue.test', 'ui.router.queue.test.dependency');

inject(function ($state) {
var list = $state.get().sort(function(a, b) { return (a.name > b.name) - (b.name > a.name); });
expect(list.map(function(state) { return state.name; })).toEqual(expectedStates);
});
});

it('should work when parent is name string', function() {
module('ui.router.queue.test', 'ui.router.queue.test.dependency');

inject(function ($state) {
var list = $state.get().sort(function(a, b) { return (a.name > b.name) - (b.name > a.name); });
expect(list.map(function(state) { return state.name; })).toEqual(expectedStates);
});
});
});

0 comments on commit 5cac9e7

Please sign in to comment.