Skip to content

Commit 8dd978d

Browse files
fix($state): queue all state registration until runtime. closes #1435
- 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.
1 parent 100267c commit 8dd978d

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

src/state.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider'];
2323
function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
2424

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

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

159+
function flushQueuedChildren(parentName) {
160+
var queued = queue[parentName] || [];
161+
while(queued.length) {
162+
registerState(queued.shift());
163+
}
164+
}
165+
159166
function registerState(state) {
160167
// Wrap a new object around the state so we can store our private details easily.
161168
state = inherit(state, {
@@ -171,10 +178,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
171178
// Get parent name
172179
var parentName = (name.indexOf('.') !== -1) ? name.substring(0, name.lastIndexOf('.'))
173180
: (isString(state.parent)) ? state.parent
181+
: (isObject(state.parent) && isString(state.parent.name)) ? state.parent.name
174182
: '';
175183

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

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

195203
// Register any queued children
196-
if (queue[name]) {
197-
for (var i = 0; i < queue[name].length; i++) {
198-
registerState(queue[name][i]);
199-
}
200-
}
204+
flushQueuedChildren(name);
201205

202206
return state;
203207
}
@@ -523,8 +527,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
523527
* you're coming from.
524528
*/
525529
this.$get = $get;
526-
$get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter'];
527-
function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $urlRouter) {
530+
$get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter', '$location', '$urlMatcherFactory'];
531+
function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $urlRouter, $location, $urlMatcherFactory) {
528532

529533
var TransitionSuperseded = $q.reject(new Error('transition superseded'));
530534
var TransitionPrevented = $q.reject(new Error('transition prevented'));
@@ -1192,6 +1196,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
11921196
});
11931197
}
11941198

1199+
isRuntime = true;
1200+
flushQueuedChildren("");
1201+
11951202
return $state;
11961203
}
11971204

test/stateSpec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1049,9 +1049,9 @@ describe('state', function () {
10491049

10501050
describe('provider decorators', function () {
10511051

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

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

0 commit comments

Comments
 (0)