Búsqueda de sitios web

javascript - AngularJS y Typescript - Inyección de servicios


He estado escribiendo aplicaciones AngularJS durante un tiempo, pero Typescript es nuevo para mí, y luego agregar AngularJS a Typescript es un poco diferente de lo que estoy acostumbrado.

De todos modos, ¿cuál es la diferencia entre los dos:

app.service('customerDataService', Application.Services.CustomerDataService);

y

app.service('customerDataService', ['$http', '$q', Application.Services.CustomerDataService]);

Controlador TS

module Application {
    export module Services {
        export interface ICustomerDataService {
            getCustomer(id: number): ng.IPromise<Models.ICustomer>;
        }

        export class CustomerDataService implements ICustomerDataService {
            constructor(private $http: ng.IHttpService, private $q: ng.IQService) {
            }

            getCustomer(id: number): ng.IPromise<Models.ICustomer> {
                return this.$http.get('data/Customer.json').then((response) => {
                    return response.data;
                });
            }
        }
    }
}

App TS

var app = angular.module('app', []);

app.value('config', new Application.ApplicationConfig());

app.service('customerDataService', ['$http', '$q', Application.Services.CustomerDataService]);
app.service('customerDataService', Application.Services.CustomerDataService);

app.controller('DefaultController', ['$scope','config', 'customerDataService', Application.Controllers.DefaultController]);

Ambos parecen funcionar. ¿Tienes que definir explícitamente las inyecciones para un servicio?

Respuesta #1

Sí necesitas inyectar dependencias para el servicio o cualquier otra entidad de Angular (providers, factories, controllers, etc.) al minificar el código. En un código no minificado, sí, ambos enfoques funcionarán.

Considera el constructor:-

 constructor(private $http: ng.IHttpService, private $q: ng.IQService) {
 }

Caso 1 [Anotación explícita de dependencia]:

app.service('customerDataService', ['$http', '$q', Application.Services.CustomerDataService]);

No hay problemas en la minificación tampoco, porque incluso si el minificador cambia $http a, por ejemplo, a y $q a, por ejemplo, b, seguirá funcionando porque Angular usará internamente annotate para derivar las dependencias del arreglo que proporcionas al definir el servicio.

Caso 2 [dependencias implícitas]:

app.service('customerDataService', Application.Services.CustomerDataService);

En este caso, si el $http se cambia a decir a y $q se cambia a b, Angular buscará aProvider y bProvider al instanciar tu servicio y, en última instancia, tu aplicación fallará cuando se ejecute con archivos minificados, ya que no había nada listado como dependencias, el parser de Angular tendrá que analizar la definición del método y los nombres de los argumentos del método para descubrir las dependencias.

Otra forma en la que puedes inyectar dependencias es usando la propiedad $inject definida en la función (cTor) (no en la instancia). Podrías hacer:-

    export class CustomerDataService implements ICustomerDataService {
        static $inject = ['$http', '$q']; //<-- Inject here

        constructor(private $http: ng.IHttpService, private $q: ng.IQService) {
      }
      ....

y justo:-

   app.service('customerDataService', Application.Services.CustomerDataService);

Y listar tus dependencias a veces también ayuda a usar un nombre alternativo para los nombres de los argumentos del servicio inyectado. Si no quieres hacer todo esto y aún así que tu código funcione con el minificador, podrías usar la biblioteca ng-annotate.

Con Angular 1.3 rc, hay una opción llamada strict-di que puedes especificar en tu rootElement para hacer cumplir la inyección de dependencias explícitamente anotada en cualquier servicio o cualquier entidad de Angular que será instanciada durante la vida de tu aplicación. Si usas esta opción y algún servicio o similar no está anotado explícitamente, fallará durante la instanciación.

Artículos relacionados