Tentando definir dinamicamente um templateUrl no controlador com base na constante

Eu quero mudar o templateUrl associado ao controlador com base em uma constante predefinida que eu defini no bootstrap angularjs. Eu não consigo descobrir como mudar isso. Eu experimentei o UrlRouteProvider, mas não consegui descobrir como puxar o html do sistema de arquivos com isso. Estou preso no templateUrl.

No código abaixo, a saída primeiro mostra que “svcc é de fato passado para o console.out da primeira function, mas na function de definição templateUrl, o CONFIG é indefinido.

Estou aberto a outras maneiras de fazer isso.

var app = angular.module('svccApp', [ 'ui.router' ]); var myConstant = {}; myConstant.codeCampType = "svcc"; app.constant("CONFIG", myConstant); app.config(['$stateProvider', '$urlRouterProvider','CONFIG', function ($stateProvider, $urlRouterProvider,CONFIG) { console.log(CONFIG.codeCampType); $stateProvider .state('home', { url: '/home', //templateUrl: 'index5templateA.html', (THIS WORKS) templateUrl: function(CONFIG) { console.log('in templateUrl ' + CONFIG.codeCampType); if (CONFIG.codeCampType === "svcc") { return 'index5templateA.html'; } else { return 'index5templateB.html'; } }, controller: function ($state) { } }); }]); 

Eu criei um plunker aqui Você está quase lá, apenas a syntax é 'templateProvider' :

 .state('home', { url: '/home', //templateUrl: 'index5templateA.html', (THIS WORKS) // templateUrl: function(CONFIG) { templateProvider: function(CONFIG) { ... 

Snippet do documento:

Modelos

TemplateUrl
templateUrl também pode ser uma function que retorna um URL. Leva um parâmetro predefinido, stateParams , que NÃO é injetado.

TemplateProvider
Ou você pode usar uma function de provedor de modelo que pode ser injetada, tem access a locais e deve retornar HTML de modelo, como este:

Então, no nosso caso, isso seria a implementação:

  $stateProvider .state('home', { url: '/home', //templateUrl: 'index5templateA.html', (THIS WORKS) templateProvider: function(CONFIG, $http, $templateCache) { console.log('in templateUrl ' + CONFIG.codeCampType); var templateName = 'index5templateB.html'; if (CONFIG.codeCampType === "svcc") { templateName = 'index5templateA.html'; } var tpl = $templateCache.get(templateName); if(tpl){ return tpl; } return $http .get(templateName) .then(function(response){ tpl = response.data $templateCache.put(templateName, tpl); return tpl; }); }, controller: function ($state) { } }); 

Confira o exame aqui

Verifique também:

  • Roteador de IU Angular: decide o modelo de estado filho com base no object resolvido pai
  • Angular e UI-Router, como definir um templateUrl dynamic

Eu tenho que adicionar outra resposta, relacionada ao novo recurso de 1.3 angular

$ templateRequest

O serviço $templateRequest download do modelo fornecido usando $http e, com sucesso, armazena o conteúdo dentro de $templateCache .

Uso

 $templateRequest(tpl, [ignoreRequestError]); 

Argumentos – string tpl – O URL do modelo de solicitação HTTP

  • ignoreRequestError (opcional) booleano – Se deve ou não ignorar a exceção quando a solicitação falhar ou o modelo estiver vazio

E atualizado plunker

 templateProvider: function(CONFIG, $templateRequest) { console.log('in templateUrl ' + CONFIG.codeCampType); var templateName = 'index5templateB.html'; if (CONFIG.codeCampType === "svcc") { templateName = 'index5templateA.html'; } return $templateRequest(templateName); }, 
  var app = angular.module('svccApp', [ 'ui.router' ]); var myConstant = {}; myConstant.codeCampType = "svcc"; app.config(['$stateProvider', '$urlRouterProvider','CONFIG', function ($stateProvider, $urlRouterProvider,CONFIG) { console.log(CONFIG.codeCampType); $stateProvider .state('home', { url: '/home', //templateUrl: 'index5templateA.html', (THIS WORKS) templateUrl: function() { if (myConstant.codeCampType === "svcc") { return 'index5templateA.html'; } else { return 'index5templateB.html'; } }, controller: function ($state) { } }); }]);