¿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í