Angular y UI-Router, cómo configurar una plantilla dinámicaUrl

¿Cómo podría usar un nombre obtenido de mi base de datos como templateUrl filename?

He intentado esto:

$stateProvider.state('/', { url: '/', views: { page: { controller: 'HomeCtrl', templateProvider: function($templateFactory, $rootScope) { console.log("$rootScope.template") return $templateFactory.fromUrl('/templates/' + $rootScope.template); } } } }); 

Lo cual no parece funcionar si mi $ rootScope.template proviene de una consulta de base de datos. No sé por qué, pero no funciona.

Si en mi controlador hago $ rootScope.template = “whatever.html” todo funciona bien, pero si consulto la plantilla desde la base de datos, nada sucede. console.log (“$ rootScope.template”) en templateProvider no me da nada (la consulta en sí funciona bien).

¿La consulta simplemente lleva demasiado tiempo y, por lo tanto, no está lista para el enrutador o lo que está sucediendo aquí?

Eso estoy haciendo mal y cómo puedo solucionarlo?

Como se discutió en esta sección de Preguntas y respuestas: Enrutador de UI angular: decida la plantilla de estado hijo sobre la base del objeto resuelto padre , podemos hacerlo de esta manera

Esta podría ser una función de servicio de “del nombre de plantilla de carga de Servidor / DB”:

 .factory('GetName', ['$http', '$timeout', function($http, $timeout) { return { get : function(id) { // let's pretend server async delay return $timeout(function(){ // super simplified switch... but ... var name = id == 1 ? "views.view2.html" : "views.view2.second.html" ; return {templateName : name}; }, 500); }, }; } ]); 

Entonces la definición de templateProvider se vería así:

  views: { "page": { templateProvider: function($http, $stateParams, GetName) { // async service to get template name from DB return GetName .get($stateParams.someSwitch) // now we have a name .then(function(obj){ return $http // let's ask for a template .get(obj.templateName) .then(function(tpl){ // haleluja... return template return tpl.data; }); }) }, 

El código debe ser auto explicativo. Verifique esta respuesta y su plunker para más detalles

Creé un ejemplo, que usa algo json para cargar como datos del servidor, verifíquelo aquí . Esto es lo que los $http recibirán (en nuestro ejemplo simplificado)

 // dataFromServer.json { "1": "views.view2.html", "2": "views.view2.second.html" } 

Así que esto vendrá a través de $ http y lo usaremos para devolver el nombre

 .factory('GetName', ['$http', '$timeout', function($http, $timeout) { return { get : function(id) { // let's get data via $http // here it is the list, but // should be some GetById method return $http .get("dataFromServer.json") .then(function(response){ // simplified converter // taking the $http result and // by id gets the name var converter = response.data; var name = converter[id]; return {templateName : name}; }); }, }; } 

Como podemos ver, esta vez, realmente buscamos datos del servidor, usando $http el truco nuevamente es devolver esa promesa

 return $http // see the return .get.... 

y luego, volvemos de nuevo … dentro del entonces

 .... .then(function(response){ ... return {templateName : name}; }); 

Ese ejemplo está aquí