diff --git a/src/state.js b/src/state.js index 5901f4141..62d504ba0 100644 --- a/src/state.js +++ b/src/state.js @@ -1390,30 +1390,38 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) { })]; if (inherited) promises.push(inherited); - // Resolve template and dependencies for all views. - forEach(state.views, function (view, name) { - var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {}); - injectables.$template = [ function () { - return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: options.notify }) || ''; - }]; - - promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) { - // References to the controller (only instantiated at link time) - if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) { - var injectLocals = angular.extend({}, injectables, locals, result); - result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals); - } else { - result.$$controller = view.controller; - } - // Provide access to the state itself for internal use - result.$$state = state; - result.$$controllerAs = view.controllerAs; - dst[name] = result; - })); - }); + function resolveViews() { + var viewsPromises = []; + + // Resolve template and dependencies for all views. + forEach(state.views, function (view, name) { + var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {}); + injectables.$template = [ function () { + return $view.load(name, { view: view, locals: dst.globals, params: $stateParams, notify: options.notify }) || ''; + }]; + + viewsPromises.push($resolve.resolve(injectables, dst.globals, dst.resolve, state).then(function (result) { + // References to the controller (only instantiated at link time) + if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) { + var injectLocals = angular.extend({}, injectables, dst.globals); + result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals); + } else { + result.$$controller = view.controller; + } + // Provide access to the state itself for internal use + result.$$state = state; + result.$$controllerAs = view.controllerAs; + dst[name] = result; + })); + }); + + return $q.all(viewsPromises).then(function(){ + return dst.globals; + }); + } // Wait for all the promises and then return the activation object - return $q.all(promises).then(function (values) { + return $q.all(promises).then(resolveViews).then(function (values) { return dst; }); } diff --git a/test/stateSpec.js b/test/stateSpec.js index aae3e7524..6067e3d65 100644 --- a/test/stateSpec.js +++ b/test/stateSpec.js @@ -1,6 +1,6 @@ describe('state', function () { - var stateProvider, locationProvider, templateParams, ctrlName; + var stateProvider, locationProvider, templateParams, ctrlName, template; beforeEach(module('ui.router', function($locationProvider) { locationProvider = $locationProvider; @@ -78,6 +78,16 @@ describe('state', function () { foo: function() { return 'Foo'; } } }) + .state('dynamicTemplate', { + url: "/dynamicTemplate/:type", + templateProvider: function($stateParams, foo) { + template = $stateParams.type + foo + "Template"; + return template; + }, + resolve: { + foo: function() { return 'Foo'; } + } + }) .state('home.redirect', { url: "redir", onEnter: function($state) { @@ -490,6 +500,12 @@ describe('state', function () { expect(ctrlName).toEqual("AcmeFooController"); }));+ + it('uses the templateProvider to get template dynamically', inject(function ($state, $q) { + $state.transitionTo('dynamicTemplate', { type: "Acme" }); + $q.flush(); + expect(template).toEqual("AcmeFooTemplate"); + })); + it('updates the location #fragment, if specified', inject(function ($state, $q, $location) { // html5mode disabled locationProvider.html5Mode(false); @@ -929,6 +945,7 @@ describe('state', function () { 'badParam', 'badParam2', 'dynamicController', + 'dynamicTemplate', 'first', 'home', 'home.item',