AngularJS和Typescript - 注入服务

10

我已经写了一段时间的AngularJS应用程序,但是Typescript对我来说是新的,将AngularJS添加到Typescript中与我过去使用的有点不同。

无论如何,这两者之间有什么区别:

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

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

Controller 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;
                });
            }
        }
    }
}

应用程序 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]);

它们似乎都可以工作。你必须明确地为服务定义注入吗?


如果你不进行代码压缩或者使用 ng-annotate,就不一定需要注入依赖项。你也可以通过定义静态 $inject 属性在服务类中定义依赖项:static $inject = ['$http', '$q']。有时使用注入还可以使用更好的变量名... 但是,如果你打开了严格模式(strict-di),在 Angular 1.3 中你必须列出你的依赖项。 - PSL
2个回答

18

在代码被压缩(minify)时,您需要注入依赖项以供服务或任何其他Angular实体(提供商、工厂、控制器等)使用。在非压缩的代码中,这两种方法都可以使用。

考虑构造函数:

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

案例1 [显式依赖注释]:

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

即使压缩器将$http更改为a ,将$q更改为b,也不会有缩小问题,因为Angular将在内部使用annotate从提供定义服务的数组中派生依赖项,以确保代码正常工作。

情况2 [隐式依赖项]:

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

如果将$http更改为a,将$q更改为b,Angular将在实例化服务时查找aProvider和bProvider,因为没有列出依赖项,所以解析器将需要解析方法定义和参数名称来发现依赖关系。这样,在最小化文件的情况下运行您的应用程序时,您的应用程序最终会失败。

另一种注入依赖项的方法是使用函数(cTor)上定义的$inject属性(而不是实例)。您可以这样做:

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

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

并且只需要:

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

有时列出依赖项还可以帮助您为注入的服务参数名称使用替代名称。 如果您不想进行所有这些操作,但仍要使代码与缩小器一起工作,则可以选择使用ng-annotate库。


在Angular 1.3 rc中,有一个名为strict-di的选项,您可以在rootElement上指定它,以强制执行显式注释的依赖项注入,在应用程序生命周期内实例化任何服务或任何angular实体。如果您使用此选项,并且存在未明确注释的任何服务,则将在实例化期间失败。


0

这两种方式本质上是相同的,但在第一种方式中,当进行代码压缩时,依赖项的名称会被更改,从而导致代码出错。因此,在第二种方式中,您需要提供一个依赖项数组,以确保压缩算法不会对其进行更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接