Angular2 中的依赖注入
在angular2应用中依赖注入将会大量的应用在我们所创建的服务中,至于依赖注入的原理及特点在此不做深究,网上大量资料介绍依赖注入,本节重点是如何在angular2 RC1中应用依赖注入(Dependency injection)。
依赖注入的申明
我们要想让一个服务或组件能够被其他组件或服务注入,就需要对其进行标记,在angular2中可以使用@Injectable()进行标记。示例如下:
/**
* Created by Administrator on2016-06-15.
*/
import {Injectable} from "@angular/core";
@Injectable()
export class MyService
{
name:string="原始";
changeName(name:string){
this.name=name;
}
}
这是一个简单的服务,对外提供一个属性及改变属性的方法,通过@Injectable()来标记这个服务是可被注入的,注意这个标记后有‘()’。
依赖注入的使用
要引入依赖注入也很简单,我们只需在构造函数中引入即可,示例:
/**
* Created by Administrator on2016-06-15.
*/
import {Component} from "@angular/core";
import {childCmp} from"./child";
import {MyService} from"./service";
@Component({
selector:'parent',
directives:[childCmp],
providers:[MyService],
template:`
<div class="panel panel-info">
<div class="panel panel-heading">
<p class="panel-title">{{title}}</p>
</div>
<divclass="panel-body">
<input type="text" #parentInput (keyup)="parentData=parentInput.value"/>
<button (click)="onclick()">获取标题</button>
<child [parentValue]="parentInput.value" (childValueChanged)="childData=$event" ></child>
</div>
</div>
})
export class parentCmp{
title : string ;
childData : string ;
parentData : string ;
constructor ( private myService:MyService){
this .myService. changeName ( "父组件" );
this . title =myService. name ;
}
onclick()
{
this.title=this.myService.name;
}
}
在anglar2中使用所需的注入对象时都要去查找该对象的provider,在本示例中我们在@Component中申明了这个providers:[MyService],这意味着该组件实例化了一个MyService,这个MyService将会在该组件及其子组件中保持唯一的一个实例,也就是说在该组件的子组件无需再次声明这个provider,它们就共享这个实例。来看看子组件的示例:
/**
* Created by Administrator on2016-06-15.
*/
import {Component, Input, Output,EventEmitter} from "@angular/core";
import {MyService} from"./service";
@Component({
selector:'child',
template:`
<div class="panel panel-danger">
<div class="panel panel-heading">
<p class="panel-title">{{title}}</p>
</div>
<div class="panel-body">
<p>这是父组件数据:{{parentValue}}</p>
<input type="text" #childInput (keyup)="onChanged(childInput.value)"/>
<button (click)="onClick()">change title</button>
</div>
</div>
})
export class childCmp{
title:string;
private _parentValue:string;
constructor(private myService:MyService){
this.title=myService.name;
}
@Input()
get parentValue():string{
if(this._parentValue!=="")
return "From:"+this._parentValue
else
return "";
}
set parentValue(value:string){
this._parentValue=value;
if(value!=="")
this.childValueChanged.emit("From:"+value);
}
@Output()childValueChanged=newEventEmitter<string>()
onChanged(inputValue:string){
this.childValueChanged.emit(inputValue);
}
onClick(){
this.myService.name="子组件";
}
}
在angular2中依赖注入将会由下向上查找注入对象的provider,直到找到为止并共享该实例,如果找不到provider那么将会引发异常,这个异常在编译期间是无法捕获的。
angular2全局依赖注入
前面讲到在angular2中依赖注入将会自下而上查找provider,联系到我们的实际应用,我们常会有些服务在整个应用中都要保持唯一实例(singleton),比如用户登录信息。一种最好的方式是在bootstrap时就实例化这个服务,具体实现看示例:
import { bootstrap } from '@angular/platform-browser-dynamic';
import {myApp} from "./myApp";
import {MyService} from"./DependencyInject/service";
bootstrap(myApp,[MyService]).catch(err=>console.error(err));