Skip to content

Commit

Permalink
fix($state): queue all state registration until runtime. closes #1435
Browse files Browse the repository at this point in the history
- param Type(s) are not available until runtime because they can be injected. UrlMatcher requires Type. StateBuilder creates UrlMatchers. Therefore, states must be built JIT at runtime.
  • Loading branch information
christopherthielen committed Oct 20, 2014
1 parent b1379e6 commit 838b747
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
25 changes: 16 additions & 9 deletions src/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider'];
function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {

var root, states = {}, $state, queue = {}, abstractKey = 'abstract';
var root, states = {}, $state, queue = {}, abstractKey = 'abstract', isRuntime = false;

// Builds state properties from definition passed to registerState()
var stateBuilder = {
Expand Down Expand Up @@ -156,6 +156,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
queue[parentName].push(state);
}

function flushQueuedChildren(parentName) {
var queued = queue[parentName] || [];
while(queued.length) {
registerState(queued.shift());
}
}

function registerState(state) {
// Wrap a new object around the state so we can store our private details easily.
state = inherit(state, {
Expand All @@ -171,10 +178,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
// Get parent name
var parentName = (name.indexOf('.') !== -1) ? name.substring(0, name.lastIndexOf('.'))
: (isString(state.parent)) ? state.parent
: (isObject(state.parent) && isString(state.parent.name)) ? state.parent.name
: '';

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

Expand All @@ -193,11 +201,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
}

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

return state;
}
Expand Down Expand Up @@ -523,8 +527,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* you're coming from.
*/
this.$get = $get;
$get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter'];
function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $urlRouter) {
$get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter', '$location', '$urlMatcherFactory'];
function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $urlRouter, $location, $urlMatcherFactory) {

var TransitionSuperseded = $q.reject(new Error('transition superseded'));
var TransitionPrevented = $q.reject(new Error('transition prevented'));
Expand Down Expand Up @@ -1192,6 +1196,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
});
}

isRuntime = true;
flushQueuedChildren("");

return $state;
}

Expand Down
4 changes: 2 additions & 2 deletions test/stateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1049,9 +1049,9 @@ describe('state', function () {

describe('provider decorators', function () {

it('should return built-in decorators', function () {
it('should return built-in decorators', inject(function ($state) {
expect(stateProvider.decorator('parent')({ parent: A }).self.name).toBe("A");
});
}));

it('should allow built-in decorators to be overridden', inject(function ($state, $q) {
stateProvider.decorator('data', function(state) {
Expand Down

0 comments on commit 838b747

Please sign in to comment.