AngularJS 和 Typescript - 注入服务 [英] AngularJS and Typescript - Injecting Services

查看:20
本文介绍了AngularJS 和 Typescript - 注入服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写 AngularJS 应用程序有一段时间了,但 Typescript 对我来说是新的,然后将 AngularJS 添加到 Typescript 与我习惯的有点不同.

不管怎样,两者有什么区别:

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

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

控制器 TS

模块应用{导出模块服务{导出接口 ICustomerDataService {getCustomer(id: number): ng.IPromise;}导出类 CustomerDataService 实现 ICustomerDataService {构造函数(私有 $http:ng.IHttpService,私有 $q:ng.IQService){}getCustomer(id: number): ng.IPromise{返回 this.$http.get('data/Customer.json').then((response) => {返回 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]);

它们似乎都有效.您是否必须明确定义服务的注入?

解决方案

在缩小代码时,您确实需要为服务或任何其他角度实体(提供者、工厂、控制器等)注入依赖项.在非缩小代码中,两种方法都可以.

考虑构造函数:-

 构造函数(私有 $http: ng.IHttpService, 私有 $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 更改为 bangular 将在实例化您的服务时查找 aProvider 和 bProvider,最终您的应用程序在使用缩小的文件运行时将失败,因为没有列出任何依赖项 angular 解析器必须解析方法定义和方法的参数名称以发现依赖项.

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

 导出类 CustomerDataService 实现 ICustomerDataService {静态 $inject = ['$http', '$q'];//<-- 在这里注入构造函数(私有 $http:ng.IHttpService,私有 $q:ng.IQService){}....

而且只是:-

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

列出您的依赖项有时也有助于为注入的服务参数名称使用替代名称.如果你不想做所有这些并且仍然让你的代码使用 minifier,你可以使用 ng-annotate 图书馆.

<小时>

使用 angular 1.3 rc,有一个名为 strict-di 的选项,您可以在rootElement 对将在您的应用程序生命周期内实例化的任何服务或任何角度实体强制执行显式注释的依赖项注入.如果您使用此选项,并且任何未显式注释的服务等将在实例化过程中失败.

I have been writing AngularJS apps for awhile now, but Typescript is new to me, and then adding in AngularJS to Typescript is a bit different than I am use to.

Anyways, what is the difference between the two:

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

and

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

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]);

They both seem to work. Do you have to explicitly define the injections for a service?

解决方案

You do need to inject dependencies for service or any other angular entities (providers, factories, controllers etc..) when minifying the code. In a non minified code yes both approaches will work.

Consider the constructor:-

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

Case 1 [Explicit dependency annotation]:-

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

No issues in minification as well because even if the minifier changes $http to say a and $q to say b it will still work because angular will internally use annotate to derive the dependencies from the array that you provide defining the service.

Case 2 [implicit dependencies]:-

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

In this case if the $http is changes to say a and $q is changed to b angular will look for aProvider and bProvider while instantiating your service and ultimately you app will fail when run with minified files, since there was nothing listed as dependencies angular parser will have to parse the method definition and method's argument names to discover the dependencies.

Another way you can inject dependencies is by using $inject property defined on the function (cTor) (not on the instance). You could do:-

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

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

and just:-

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

And listing your dependencies sometimes also help use an alternate name for the injected service argument names. If you dont want to do all these and still have your code work with minifier you could go with ng-annotate library.


With angular 1.3 rc, there is an option called strict-di which you can specify with on your rootElement to enforce explicitly annotated dependency injection on any service or any angular entities that will be instantiated during your app lifetime. If you use this option and any services or so that are not explicitly annotated will fail during instantiation.

这篇关于AngularJS 和 Typescript - 注入服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆