Angular e UI-Router, como definir um templateUrl dynamic

Como eu poderia usar um nome buscado no meu database como um nome de arquivo templateUrl?

Eu tentei isso:

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

O que parece não funcionar se meu $ rootScope.template vier de uma consulta ao database. Não sei porque, mas não funciona.

Se no meu controller eu faço $ rootScope.template = “whatever.html” tudo funciona ok, mas se eu consultar o template do database nada acontece. O console.log (“$ rootScope.template”) no templateProvider não me dá nada (a consulta funciona bem).

A consulta demora muito e, portanto, não está pronta para o roteador ou o que está acontecendo aqui?

Que estou fazendo errado e como posso consertar isso?

Como discutido neste Q & A: Angular UI Router: decidir modelo de estado infantil com base no object resolvido pai , podemos fazer isso assim

Este poderia ser um serviço desempenhando o papel de “do nome do modelo de carregamento do servidor / database”:

 .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); }, }; } ]); 

Em seguida, a definição templateProvider ficaria assim:

  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; }); }) }, 

O código deve ser auto explicativo. Verifique esta resposta e sua plunker para mais detalhes

Eu criei um exemplo, que usa algum json para ser carregado como dados do servidor, confira aqui . Isso que o $http vai receber (no nosso exemplo simplificado)

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

Então, isso virá via $ http e nós vamos usá-lo para retornar o nome

 .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, desta vez, nós realmente vamos para os dados do servidor, usando $http o truque é voltar a promise

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

e depois, voltamos de novo … dentro do então

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

Esse exemplo está aqui