Quiero inyectar un servicio en app.config, para que los datos puedan recuperarse antes de que se llame al controlador. Lo intenté así:
Servicio:
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(),
}
})
});
Pero me sale este error:
Error: proveedor desconocido: dbService de EditorApp
¿Cómo corregir la configuración e inyectar este servicio?
Respuestas:
Alex proporcionó la razón correcta para no poder hacer lo que estás tratando de hacer, entonces +1. Pero está encontrando este problema porque no está utilizando del todo resuelve cómo están diseñados.
resolve
toma la cadena de un servicio o una función que devuelve un valor a inyectar. Como estás haciendo lo último, debes pasar una función real:Cuando el marco se resuelva
data
, inyectarádbService
en la función para que pueda usarlo libremente. No necesita inyectarse en elconfig
bloque para lograr esto.¡Buen provecho!
fuente
.service
, así que muévase$q
y$http
allí.pageData: 'myData'
, pero luego tendría que llamarpageData.overview
desde su controlador. El método de cadena probablemente solo sea útil si la fábrica de servicios devolvió una promesa en lugar de una API. Entonces, la forma en que lo estás haciendo es probablemente la mejor.Configure su servicio como un proveedor personalizado de AngularJS
A pesar de lo que dice la respuesta aceptada, en realidad PUEDES hacer lo que pretendías hacer, pero debes configurarlo como un proveedor configurable, para que esté disponible como un servicio durante la fase de configuración. Primero, cambia tu
Service
a un proveedor Como se muestra abajo. La diferencia clave aquí es que después de establecer el valor dedefer
, establece ladefer.promise
propiedad en el objeto de promesa devuelto por$http.get
:Servicio de proveedor: (proveedor: receta de servicio)
Ahora, tiene un proveedor personalizado configurable, solo necesita inyectarlo. La diferencia clave aquí es la falta de "Proveedor en su inyectable".
config:
utilizar datos resueltos en su
appCtrl
Posibles alternativas
La siguiente alternativa es un enfoque similar, pero permite que la definición ocurra dentro del
.config
encapsulado del servicio dentro del módulo específico en el contexto de su aplicación. Elija el método adecuado para usted. También vea a continuación las notas sobre una tercera alternativa y enlaces útiles para ayudarlo a entender todas estas cosasAlgunos recursos útiles
$http
específica en el contexto de esta solicitudfactory
/service
/provider
en clevertech.biz .El proveedor le brinda un poco más de configuración sobre el
.service
método, lo que lo hace mejor como proveedor de nivel de aplicación, pero también puede encapsular esto dentro del propio objeto de configuración al inyectar$provide
en la configuración de la siguiente manera:fuente
$get
llamada. En su lugar, desea agregar métodos en la instancia del proveedor y simplemente regresarthis
cuando llame$get
. De hecho, en su ejemplo, podría usar un servicio ... En un proveedor tampoco puede inyectar servicios como$http
. Y por cierto esto//return the factory as a provider, that is available during the configuration phase
es información engañosa / incorrectaRespuesta corta: no puedes. AngularJS no le permitirá inyectar servicios en la configuración porque no puede estar seguro de que se hayan cargado correctamente.
Vea esta pregunta y respuesta: inyección de valor de dependencia AngularJS dentro del módulo.config
fuente
No creo que se supone que puedas hacer esto, pero he inyectado con éxito un servicio en un
config
bloque. (AngularJS v1.0.7)fuente
.config
usted ha escrito cacheBuster (que no está definido en ninguna parte de la respuesta) y dogmaCacheBusterProvider (que no se usa más). ¿Vas a aclarar sobre esto?cacheBuster
está definido, como un parámetro de la función de configuración. Con respecto a estodogmaCacheBusterProvider
, es algo inteligente que Angular hace con las convenciones de nombres, que hace mucho tiempo he olvidado. Esto podría acercarte, stackoverflow.com/a/20881705/110010 ..provider()
receta. ¿Qué pasa si defino algo con.factory('ServiceName')
o.service('ServiceName')
receta y quiero usar uno de sus métodos en.config
bloque? Establezco el parámetro como ServiceNameProvider pero detiene mi aplicación.Puede usar el servicio $ inject para inyectar un servicio en su configuración
Fuente: http://odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx
** Solicitar servicios explícitamente de otros módulos usando angular.injector **
Solo para explicar la respuesta de kim3er , puede proporcionar servicios, fábricas, etc. sin cambiarlos a proveedores, siempre que estén incluidos en otros módulos ...
Sin embargo, no estoy seguro de si el
*Provider
(que se realiza internamente por angular después de que procesa un servicio o una fábrica) siempre estará disponible (puede depender de qué más se cargue primero), ya que angular carga perezosamente los módulos.Tenga en cuenta que si desea volver a inyectar los valores, deben tratarse como constantes.
Aquí hay una forma más explícita y probablemente más confiable de hacerlo + un explotador en funcionamiento
fuente
Usar $ injector para llamar a los métodos de servicio en la configuración
Tuve un problema similar y lo resolví utilizando el servicio $ injector como se muestra arriba. Intenté inyectar el servicio directamente pero terminé con una dependencia circular en $ http. El servicio muestra un modal con el error y estoy usando el modal ui-bootstrap que también depende de $ https.
fuente
Una solución muy fácil de hacer.
Nota : es solo para una llamada asíncrona, porque el servicio no se inicializa en la ejecución de la configuración.
Puedes usar el
run()
método. Ejemplo:Tu codigo :
fuente
Bueno, luché un poco con este, pero en realidad lo hice.
No sé si las respuestas están desactualizadas debido a algún cambio en angular, pero puede hacerlo de esta manera:
Este es tu servicio:
Y esta es la configuración
fuente
La manera más fácil:
$injector = angular.element(document.body).injector()
Luego usa eso para correr
invoke()
oget()
fuente