Quais provedores/serviços estão disponíveis no module.config?
-
11-12-2019 - |
Pergunta
Quero usar $document para obter um valor de servidor de um campo de entrada.
var base_url = $document[0].getElementById('BaseUrl').value;
O URL base é usado para obter modelos.
var base_url = $document[0].getElementById('BaseUrl').value;
$routeProvider.when('/alert', {
controller: function () { },
templateUrl: base_url + '/partials/instances.html'
});
Como $document gera um erro desconhecido, suponho que não esteja disponível na configuração.Existe uma maneira de descobrir o que está disponível e o que não está?Eu também poderia usar $http para obter dados do servidor, mas isso também não está disponível.
Solução
Os módulos AngularJS são inicializados em 2 fases:
Configuration phase
onde apenas provedores e constantes estão disponíveis.Run phase
onde os serviços são instanciados com base em provedores registrados.Nesta fase, as constantes ainda estão disponíveis, mas não os provedores.
O Angular JS documentação (seção:"Carregamento e Dependências do Módulo") fornece informações sobre isso:
Um módulo é uma coleção de blocos de configuração e execução que são aplicados ao aplicativo durante o processo de bootstrap.Na sua forma mais simples, o módulo consiste na coleção de dois tipos de blocos:
Blocos de configuração - Seja executado durante a fase de registro e configuração do provedor.Somente provedores e constantes podem ser injetados em blocos de configuração.Isso evita a instanciação acidental dos serviços antes de serem totalmente configurados.
Executar blocos - Seja executado após a criação do injetor e é usado para iniciar o aplicativo.Somente instâncias e constantes podem ser injetadas em blocos de execução.Isso evita a configuração adicional do sistema durante o tempo de execução do aplicativo.
Dado o exposto, você só pode injetar constantes e provedores (marcados com o Provider
sufixo nos documentos da API).Isso provavelmente responde à sua pergunta, mas não ajuda a resolver o problema de carregamento de modelos ...
Eu me pergunto se você não poderia simplesmente usar a tag base em HTML e depois usar caminhos relativos (para a base) sem especificar caminhos absolutos?Algo parecido (desde que a base esteja configurada corretamente):
$routeProvider.when('/alert', {
controller: function () { },
templateUrl: 'partials/instances.html'
});
Outras dicas
Embora a pergunta tenha sido geralmente respondida, aqui está um pequeno acréscimo direcionado ao exemplo concreto usado na pergunta:
Como usar uma constante angular para definir o baseUrl dos seus parciais (ou para definir outras constantes representando valores do servidor e disponibilizá-los para configuração):
// file: app.js
'use strict';
/* App Module */
angular.module( 'myApp', [] )
// define the templateBaseUrl
.constant( 'templateBaseUrl', 'themes/angular/partials/' );
// use it in configuration
.config(['$routeProvider','templateBaseUrl', function($routeProvider,templateBaseUrl) {
$routeProvider
.when( '/posts', {
templateUrl : templateBaseUrl + 'post-list.html',
controller : PostListCtrl
})
.when( '/posts/:postId-:slug', {
templateUrl : templateBaseUrl + 'post-view.html',
controller : PostViewCtrl
})
.when( '/about', {
templateUrl : templateBaseUrl + 'about.html',
controller : AboutPageCtrl
})
.when( '/contact', {
templateUrl : templateBaseUrl + 'contact.html',
controller : ContactPageCtrl
})
.otherwise({
redirectTo: '/posts'
})
;
}]);
Na minha opinião, isso tem vários benefícios:
- Se você mover suas visualizações, precisará atualizar seu código apenas em um único local
- Se suas parciais estiverem profundamente aninhadas no layout do seu projeto, "templateBaseUrl" não causará tanto ruído quanto o caminho inteiro causaria
- Você pode até mudar entre caminho relativo e absoluto
- Uma resposta para uma pergunta semelhante sugere o uso do elemento base do HTML para remover a necessidade de anexar um baseUrl a cada templateUrl.Mas isso também afetou todos os outros recursos do site.Configurar apenas o URL base para os modelos não tem efeitos colaterais
Geralmente, não uso esta solução com um valor codificado como acima.É apenas um exemplo para mostrar o que fazer da maneira mais simples.Para poder copiar seu aplicativo em seu servidor, defina o valor fora de app.js, em seu arquivo de índice e gere os caminhos necessários no lado do servidor:
// file: index.php
<?php
// only depends on your project layout
$angularPartialsBaseUrl = 'themes/angular/partials/';
// this will change when you move the app around on the server
$themeBaseUrl = $_SERVER['REQUEST_URI'] . 'themes/angular';
?><!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Yii Blog Demo</title>
<script>
var myNS = myNS || {};
myNS.appConfig = myNS.appConfig || {};
myNS.appConfig.templateBaseUrl = '<?php echo $angularPartialsBaseUrl; ?>';
</script>
<script src="<?php echo $themeBaseUrl; ?>/js/vendor/angular/angular.js"></script>
<script src="<?php echo $themeBaseUrl; ?>/js/app.js"></script>
</head>
[...]
E em app.js:
// file: app.js
'use strict';
/* App Module */
angular.module( 'myApp', [] )
// define the templateBaseUrl using external appConfig
.constant( 'templateBaseUrl', myNS.appConfig.templateBaseUrl );