在angular2服务中注入服务

来源:互联网 发布:手机照片排版软件 编辑:程序博客网 时间:2024/06/05 16:11

如果你关注我们的文章 Angular2中的依赖注入,你知道DI系统在Angular中是如果运作的,它利用在我们代码上通过注解添加metadata来获取所有关于依赖的信息来解决我们的依赖关系

Angular 2 应用基本上可以用任何语言编写。只要它以某种方式编译成JavaScript,当我们使用Typescript编写我们应用时,我们使用decorator来给我们代码添加metadata,有时,我们甚至忽略一些decorator,单纯依靠类型注释。然而,事实证明,当涉及到DI,我们可能注入依赖到服务时遇到意外的行为。

本文讨论了这个意外的问题,为什么它存在,以及如何解决。

注入服务依赖

比方说我们有一个简单的Angular 2 组件有一个DataService依赖,它可能是这个样子:

@Component({  selector: 'my-app'})@View({  directives: [NgFor],  template: `    <ul>      <li *ng-for="#item in items"></li>    </ul>  `})class AppComponent {  items:Array<any>;  constructor(dataService: DataService) {    this.items = dataService.getItems();  }}

另一方面 DataService 是一个简单的类(因为它在Angualr2是一个服务),它提供了一个方法返回一些items

class DataService {  items:Array<any>;  constructor() {    this.items = [      { name: 'Christoph Burgdorf' },      { name: 'Pascal Precht' },      { name: 'thoughtram' }    ];  }  getItems() {    return this.items;  }}

当然,为了能使用DataService类型,我们必须为injector添加这个provider,当引导我们的应用时可以这样做,通过传递一个provider给boostrap();

bootstrap(AppComponent, [DataService]);

到现在为止没有什么新的内容,如果这对你来说是新内容,你可能需要先阅读我们的Angular2中的依赖注入文章。

那么问题在那里呢? 这个问题发生在当我们试图注入一个依赖进我们的服务,比如,我们可以使用Http在我们的DataService里从远程服务器获取数据,让我们快速实现这个。首先,我们需要为injector提供一个provider,让DataService知道有关http。

import {HTTP_PROVIDERS} from 'angular2/http';...bootstrap(AppComponent, [HTTP_PROVIDERS, DataService]);

Angular http模块 暴露了 HTTP_PROVIDERS,它包含了所有的我们需要用到的http操作的provider,接下来,我们需要在我们的服务中注入这个实例

import {Http} from 'angular2/http';class DataService {  items:Array<any>;  constructor(http:Http) {    ...  }  ...}

轰. 这个东西会爆炸。当我们在浏览器中运行这段代码,我们会得到以下错误:

Cannot resolve all parameters for DataService(?). Make sure they all have valid type or annotations.

这错误基本上的意思是,它不能解决DataService的Http依赖,因为Anuglar不知道该类型,因此 没有provider可以用来解决该依赖,恩。。等等,我们没有将变量类型提供给了constructor吗?

不,我们提供了,不幸的是,这是不够的,但是 在我们的AppComponent我们注入的DataService显然是在正常工作,那在这里有什么问题?

在我们的Annotation和Decorator之间的区别文章,我们获悉,decorator只是简单的为我们的代码添加metadata,我们来看下编译后的AppComponent的decorator

function AppComponent(myService) {  ...}AppComponent = __decorate([  Component({...}),  View({...}),   __metadata('design:paramtypes', [DataService])], AppComponent);

我们可以清楚地看到,AppComponent类会被__decorate函数给包装,里面包装了Component,View 和 paramtypes的metadata,

paramtypes 元素是一个告诉angular DI用来弄清楚,它必须返回一个什么类型的实例

这看起来很不错。让我们来看看被编译后的DataService,看看在那里发生了什么事情(也简化了)。

DataService = (function () {  function DataService(http) {    ...  }  return DataService;})();

哎呀。显然,在这里没有任何metadata。这是为什么?

当设置了emitDecoratorMetadata选项,TypeScript会生成metadata,然而,这并不意味着它会盲目的为我们代码的每个类或方法生成metadata,TypeScript只会对那些被decorator附加的类,方法,属性或者构造函数参数来生成相应的metadata ,否则,会产生大量的未使用的metadata代码,这不仅影响文件的大小,也对我们的应用程序运行产生影响。

这就是为什么AppComponent会生成metadata,而DataService 不生成,我们的AppComponent有一个decorator

强制生成metadata

那么我们如果才能强制TypeScript为我们生成metadata呢,我们可以做的一件事,就是用框架提供的Di decorator,正如我们在DI的其他文章中了解到,@Inject decorator用来要求某种类型的依赖

我们可以改变我们的DataService的成这样的:

import {Inject} from 'angular2/core';import {Http} from 'angular2/http';class DataService {  items:Array<any>;  constructor(@Inject(Http) http:Http) {    ...  }  ...}

问题解决。事实上,如果查看经过编译后的代码时会发现已生成需要的metadata

function DataService(http) {}DataService = __decorate([  __param(0, angular2_1.Inject(Http)),   __metadata('design:paramtypes', [Http])], DataService);

我们基本上可以在我们代码上做任何decorator,只要在class,或者构造函数参数上附加任何decorator,换一种说法,我们可以把 @Inject 移除,然后在这个类上使用别的decorator,因为这将导致TypeScript为构造函数参数生成metadata

当然。在一个类上使用一个decorator,来解决所有的问题,听起来不是很合适。幸运的是,我们可以使用Angular自带的另一个decorator。@Injectable 是一个用于Dart的metadata创建,在TypeScript,它没有任何特殊含义,然而,事实证明是非常适合我们的用例.

我们所要做的就是导入它,把它放在我们的DataService

import {Injectable} from 'angular2/core';import {Http} from 'angular2/http';@Injectable()class DataService {  items:Array<any>;  constructor(http:Http) {    ...  }  ...}

同样,它只是强制TypeScript发射需要的matadata,这个decorator在这里并没有什么特殊含义,这似乎是我们目前解决所示问题的最佳选择

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电信不限量卡限网速了怎么办 only实体店换货没有小票怎么办 运管所包车单不给盖章怎么办 上海留学生落户过了取号时间怎么办 电信固话怎么办才能显示自己公司 日本跟团签证没有资产证明怎么办 摇号手机号换了密码忘了怎么办 小客车摇号的账号密码忘了怎么办 去银行交违章罚款单子丢了怎么办 我的身份证被别人办了信用卡怎么办 北京驾驶证在深圳扣了分怎么办 c照一次被扣12分怎么办 教师资格证认定申请表填错了怎么办 外地车在北京违章没有牡丹卡怎么办 护士辞职了原单位不给延续怎么办 护士证注册的单位倒闭了怎么办 护士证注册的医院倒闭了怎么办 显示发货了但没物流信息怎么办 考科目三被别人举报了怎么办 科目一考了5没过怎么办 常州c1驾驶证满了12分怎么办 预约科目三成功后没交钱怎么办 预约成功后驾校不提交档案怎么办 c2刚满一年的驾照扣12分怎么办 怀孕6个月咳嗽很厉害怎么办 家门口有电线杆影响我建楼房怎么办 卡丢了不知道卡号怎么办 驾考网上预约用户被锁定了怎么办 人才中心拿出来的户口掉了怎么办 父母是南京集体户孩子没户口怎么办 二建挂靠中介单位不给证怎么办 小包工头遇到工人在工地摔伤怎么办 外地人买了城中村的房子改造怎么办 深圳社保怀孕了产检异地怎么办 成都公租房租满6年怎么办 二建审核资料如果照片丢失怎么办 身份证被冒用在外地办社保怎么办 蔷薇的嫩叶都被太阳晒死了怎么办 乐视手机进水了屏幕失灵怎么办 乐视手机进水了屏幕不显示怎么办 美团商家单量出现下滑怎么办