Desejo injetar um serviço no app.config, para que os dados possam ser recuperados antes que o controlador seja chamado. Eu tentei assim:
Serviço:
app.service('dbService', function() {
return {
getData: function($q, $http) {
var defer = $q.defer();
$http.get('db.php/score/getData').success(function(data) {
defer.resolve(data);
});
return defer.promise;
}
};
});
Config:
app.config(function ($routeProvider, dbService) {
$routeProvider
.when('/',
{
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data: dbService.getData(),
}
})
});
Mas eu recebo este erro:
Erro: Fornecedor desconhecido: dbService do EditorApp
Como corrigir a instalação e injetar este serviço?
Respostas:
Alex forneceu o motivo correto para não conseguir fazer o que você está tentando fazer, então marque com +1. Mas você está enfrentando esse problema porque não está usando bem resolve como eles são projetados.
resolve
pega a sequência de um serviço ou uma função retornando um valor a ser injetado. Como você está fazendo o último, você precisa passar uma função real:Quando a estrutura resolve
data
, ela injetadbService
a função na função, para que você possa usá-la livremente. Você não precisa injetar noconfig
bloco para conseguir isso.Bom apetite!
fonte
.service
, por isso, mover$q
e$http
lá.pageData: 'myData'
, mas seria necessário chamarpageData.overview
do seu controlador. O método string provavelmente será útil apenas se a fábrica de serviços retornou uma promessa em vez de uma API. Portanto, a maneira como você está fazendo isso provavelmente é a melhor.Configure seu serviço como um provedor AngularJS personalizado
Apesar do que a resposta Aceita diz, você realmente PODE fazer o que pretendia fazer, mas precisa configurá-lo como um provedor configurável, para que fique disponível como um serviço durante a fase de configuração. Primeiro, mude
Service
para um provedor como mostrado abaixo. A principal diferença aqui é que, após definir o valor dedefer
, você define adefer.promise
propriedade para o objeto de promessa retornado por$http.get
:Serviço do provedor: (provedor: receita de serviço)
Agora, você tem um provedor personalizado configurável, basta injetá-lo. A principal diferença aqui é o "Fornecedor do seu injetável" ausente.
config:
use dados resolvidos em seu
appCtrl
Alternativas possíveis
A alternativa a seguir é uma abordagem semelhante, mas permite que a definição ocorra dentro de
.config
, encapsulando o serviço para dentro do módulo específico no contexto do seu aplicativo. Escolha o método certo para você. Veja também abaixo as notas sobre um terceiro link alternativo e útil para ajudá-lo a entender tudo issoAlguns recursos úteis
$http
especificando-a no contexto desta solicitaçãofactory
/service
/provider
no clevertech.biz .O provedor fornece um pouco mais de configuração sobre o
.service
método, o que o torna melhor como provedor de nível de aplicativo, mas você também pode encapsular isso no próprio objeto de configuração, injetando o$provide
config da seguinte maneira:fonte
$get
chamada. Em vez disso, você deseja adicionar métodos à instância do provedor e retornarthis
quando ligar$get
. De fato, no seu exemplo, você pode simplesmente usar um serviço ... Em um provedor, você também não pode injetar serviços como$http
. E btw este//return the factory as a provider, that is available during the configuration phase
é enganosa / informações incorretasResposta curta: você não pode. O AngularJS não permitirá que você injete serviços na configuração porque não pode ter certeza de que eles foram carregados corretamente.
Consulte esta pergunta e resposta: Injeção de valor AngularJS dentro do module.config
fonte
Não acho que você consiga fazer isso, mas injetei com êxito um serviço em um
config
bloco. (AngularJS v1.0.7)fonte
.config
você escreveu cacheBuster (que não está definido em nenhum lugar da resposta) e dogmaCacheBusterProvider (que não é usado mais). Você vai esclarecer isso?cacheBuster
é definido como um parâmetro da função de configuração. Com relação adogmaCacheBusterProvider
, é algo inteligente que Angular faz com convenções de nomenclatura, que eu esqueci há muito tempo. Isso pode aproximá-lo, stackoverflow.com/a/20881705/110010 ..provider()
receita. e se eu definir algo com.factory('ServiceName')
ou.service('ServiceName')
receita e quiser usar um de seus métodos em.config
bloco, defina o parâmetro como ServiceNameProvider, mas ele interromperá meu aplicativo.Você pode usar o serviço $ inject para injetar um serviço na sua configuração
Fonte: http://odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx
** Solicite explicitamente serviços de outros módulos usando angular.injector **
Apenas para elaborar a resposta do kim3er , você pode fornecer serviços, fábricas, etc., sem alterá-los para provedores, desde que incluídos em outros módulos ...
No entanto, não tenho certeza se o
*Provider
(que é feito internamente pela angular após o processamento de um serviço ou fábrica) estará sempre disponível (pode depender do que mais foi carregado primeiro), pois o angular carrega preguiçosamente os módulos.Observe que se você deseja injetar novamente os valores, eles devem ser tratados como constantes.
Aqui está uma maneira mais explícita e provavelmente mais confiável de fazer isso + um desentupidor funcional
fonte
Usando $ injector para chamar métodos de serviço em config
Eu tive um problema semelhante e o resolvi usando o serviço $ injector, como mostrado acima. Tentei injetar o serviço diretamente, mas acabei com uma dependência circular de $ http. O serviço exibe um modal com o erro e estou usando o modal ui-bootstrap, que também depende de $ https.
fonte
Uma solução muito fácil de fazer
Nota : é apenas para uma chamada assíncrona, porque o serviço não é inicializado na execução da configuração.
Você pode usar o
run()
método Exemplo:Seu código :
fonte
Bem, lutei um pouco com esse, mas na verdade consegui.
Não sei se as respostas estão desatualizadas devido a alguma alteração na angular, mas você pode fazer o seguinte:
Este é o seu serviço:
E esta é a configuração
fonte
Caminho mais fácil:
$injector = angular.element(document.body).injector()
Em seguida, use isso para executar
invoke()
ouget()
fonte