javascript - example - angularjs services w3schools
use $ http dentro del proveedor personalizado en la configuraciĆ³n de la aplicaciĆ³n, angular.js (4)
La pregunta principal: ¿es posible? Lo intenté sin suerte ...
main app.js
...
var app = angular.module(''myApp'', [''services'']);
app.config([''customProvider'', function (customProvider) {
}]);
...
proveedor mismo
var services = angular.module(''services'', []);
services.provider(''custom'', function ($http) {
});
Y tengo ese error:
Uncaught Error: Unknown provider: $http from services
¿Algunas ideas?
¡Gracias!
La conclusión es:
- NO PUEDE inyectar un servicio en la sección de configuración del proveedor .
- PUEDE inyectar un servicio en la sección que inicializa el servicio del proveedor .
Detalles:
El marco angular tiene un proceso de inicialización de 2 fases:
FASE 1: Config
Durante la fase de config
, todos los proveedores se inicializan y se ejecutan todas las secciones de config
. Las secciones de config
pueden contener código que configura los objetos del proveedor y, por lo tanto, pueden inyectarse con objetos del proveedor. Sin embargo, dado que los proveedores son las fábricas para los objetos de servicio y en este momento los proveedores no están completamente inicializados / configurados -> no puede pedirle al proveedor que cree un servicio para usted en este momento -> en la etapa de configuración que no puede usar / inyectar servicios . Cuando se completa esta fase, todos los proveedores están listos (no se puede realizar más configuración del proveedor una vez que se haya completado la fase de configuración).
FASE 2: Ejecutar
Durante la fase de run
, se run
todas las secciones de ejecución. En esta etapa, los proveedores están listos y pueden crear servicios -> durante la fase de run
puede usar / inyectar servicios .
Ejemplos:
1. Inyectar el servicio $http
a la función de inicialización del proveedor NO funcionará
//ERRONEOUS angular.module(''myModule'').provider(''myProvider'', function($http) { // SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase) ... this.$get = function() { // code to initialize/configure the SERVICE goes here (executed during `run` stage) return myService; }; });
Como estamos intentando inyectar el servicio $http
en una función que se ejecuta durante la fase de config
, obtendremos un error:
Uncaught Error: Unknown provider: $http from services
Lo que este error realmente está diciendo es que $httpProvider
que se utiliza para crear el servicio $http
aún no está listo (ya que todavía estamos en la fase de config
).
2. Al inyectar el servicio $http
a la función de inicialización del servicio, funcionará:
//OK
angular.module(''myModule'').provider(''myProvider'', function() {
// SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase)
...
this.$get = function($http) {
// code to initialize/configure the SERVICE goes here (executed during `run` stage)
return myService;
};
});
Como ahora estamos inyectando el servicio en la función de inicialización del servicio, que se ejecuta durante la fase de run
, este código funcionará.
En respuesta a su pregunta, "¿Alguna idea?", Habría respondido con un "sí". ¡Pero espera hay mas!
Sugiero solo usar JQuery en la configuración. Por ejemplo:
var app = angular.module(''myApp'', [''services'']);
app.config([''$anyProvider'', function ($anyProvider) {
$.ajax({
url: ''www.something.com/api/lolol'',
success: function (result) {
$anyProvider.doSomething(result);
}
});
}]);
Esta es una vieja pregunta, parece que tenemos algo de huevo de gallina si queremos confiar en la capacidad central de la biblioteca.
En lugar de resolver el problema de una manera fundamental, lo que hice fue by-pass. Crea una directiva que envuelva todo el cuerpo. Ex.
<body ng-app="app">
<div mc-body>
Hello World
</div>
</body>
Ahora mc-body
necesita ser inicializado antes de renderizar (una vez), ej.
link: function(scope, element, attrs) {
Auth.login().then() ...
}
Auth
es un servicio o proveedor, ej.
.provider(''Auth'', function() {
... keep your auth configurations
return {
$get: function($http) {
return {
login: function() {
... do something about the http
}
}
}
}
})
Me parece que tengo control sobre el orden del bootstrap, es después de que el bootstrap regular resuelva toda la configuración del proveedor y luego trate de inicializar mc-body
directiva mc-body
.
Y esta directiva me parece que puede estar por delante del enrutamiento, porque el enrutamiento también se inyecta a través de una directiva, por ejemplo. <ui-route />
. Pero puedo estar equivocado en esto. Necesita más investigación.
Esto podría darle un poco de apalancamiento:
var initInjector = angular.injector([''ng'']);
var $http = initInjector.get(''$http'');
Pero ten cuidado, las devoluciones de llamada de éxito / error pueden mantenerte en una condición de carrera entre el inicio de la aplicación y la respuesta del servidor.