詳解Angular依賴注入
概述
依賴注入:設計模式
依賴:程序里需要的某種類型的對象。
依賴注入框架:工程化的框架

注入器Injector:用它的API創(chuàng)建依賴的實例
Provider:怎樣創(chuàng)建?(構造函數,工程函數)
Object:組件,模塊需要的依賴
依賴性注入進階=>Angular中依賴注入框架提供父子層次注入型依賴
一、依賴注入
class Id {
static getInstance(type: string): Id {
return new Id();
}
}
class Address {
constructor(provice, city, district, street) {}
}
class Person {
id: Id;
address: Address;
constructor() {
this.id = Id.getInstance("idcard");
this.address = new Address("北京", "背景", "朝陽區(qū)", "xx街道");
}
}
問題:Person需要清楚的知道Address和Id的實現細節(jié)。
ID和Address重構后,Person需要知道怎么重構。
項目規(guī)模擴大后,集成容易出問題。
class Id {
static getInstance(type: string): Id {
return new Id();
}
}
class Address {
constructor(provice, city, district, street) {}
}
class Person {
id: Id;
address: Address;
constructor(id: Id, address: Address) {
this.id = id;
this.address = address;
}
}
main(){
//把構造依賴對象,推到上一級,推調用的地方
const id = Id.getInstance("idcard");
const address = new Address("北京", "背景", "朝陽區(qū)", "xx街道");
const person = new Person(id , address);
}
Person已經不知道Id和Address的細節(jié)了。
這是最簡單的依賴注入。
問題是在main里還是需要知道細節(jié)。
思路:一級一級往上推,一直推到入口函數,入口函數來處理所有對象的構造。構造出來后提供給所有依賴的子模塊的子類。
問題:入口函數很難維護。所以需要一個依賴注入框架幫助完成。
二、Angular的依賴注入框架
從v5開始,因為速度慢,引入大量代碼已棄用,改為Injector.create。
ReflectiveInjector :用于實例化對象和解析依賴關系。import { Component ,ReflectiveInjector } from "@angular/core";resolveAndCreate接收一個provider數組,provider告訴injector應該怎樣去構造這個對象。
constructor() {
//接收一個provider數組
const injector = ReflectiveInjector.resolveAndCreate([
{
provide: Person, useClass:Person
},
{
provide: Address, useFactory: ()=>{
if(environment.production){
return new Address("北京", "背景", "朝陽區(qū)", "xx街道xx號");
}else{
return new Address("西藏", "拉薩", "xx區(qū)", "xx街道xx號");
}
}
},
{
provide: Id, useFactory:()=>{
return Id.getInstance('idcard');
}
}
]);
}
Injector:
injector相當于main函數,可以拿到所有依賴池子里的東西。
import { Component ,ReflectiveInjector, Inject} from "@angular/core";
import { OverlayContainer } from "@angular/cdk/overlay";
import { Identifiers } from "@angular/compiler";
import { stagger } from "@angular/animations";
import { environment } from 'src/environments/environment';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
})
export class AppComponent {
constructor(private oc: OverlayContainer) {
//接收一個provider數組
const injector = ReflectiveInjector.resolveAndCreate([
{
provide: Person, useClass:Person
},
{
provide: Address, useFactory: ()=>{
if(environment.production){
return new Address("北京", "背景", "朝陽區(qū)", "xx街道xx號");
}else{
return new Address("西藏", "拉薩", "xx區(qū)", "xx街道xx號");
}
}
},
{
provide: Id, useFactory:()=>{
return Id.getInstance('idcard');
}
}
]);
const person = injector.get(Person);
console.log(JSON.stringify(person));
}
}
class Id {
static getInstance(type: string): Id {
return new Id();
}
}
class Address {
provice:string;
city:string;
district:string;
street:string;
constructor(provice, city, district, street) {
this.provice=provice;
this.city=city;
this.district=district;
this.street=street;
}
}
class Person {
id: Id;
address: Address;
constructor(@Inject(Id) id, @Inject(Address )address) {
this.id = id;
this.address = address;
}
}
可以看到控制臺打印出person信息。

簡寫:
// {
// provide: Person, useClass:Person
// },
Person, //簡寫為Person
在Angular框架中,框架做了很多事,在provider數組中注冊的東西會自動注冊到池子中。
@NgModule({
imports: [HttpClientModule, SharedModule, AppRoutingModule, BrowserAnimationsModule],
declarations: [components],
exports: [components, AppRoutingModule, BrowserAnimationsModule],
providers:[
{provide:'BASE_CONFIG',useValue:'http://localhost:3000'}
]
})
constructor( @Inject('BASE_CONFIG') config) {
console.log(config); //控制臺打印出http://localhost:3000
}
Angular默認都是單例,如果想要每次注入都是一個新的實例。有兩種方法。
一,return的時候return一個方法而不是對象。
{
provide: Address, useFactory: ()=>{
return ()=>{
if(environment.production){
return new Address("北京", "背景", "朝陽區(qū)", "xx街道xx號");
}else{
return new Address("西藏", "拉薩", "xx區(qū)", "xx街道xx號");
}
}
}
},
二、利用父子Injector。
constructor(private oc: OverlayContainer) {
//接收一個provider數組
const injector = ReflectiveInjector.resolveAndCreate([
Person,
{
provide: Address, useFactory: ()=>{
if(environment.production){
return new Address("北京", "背景", "朝陽區(qū)", "xx街道xx號");
}else{
return new Address("西藏", "拉薩", "xx區(qū)", "xx街道xx號");
}
}
},
{
provide: Id, useFactory:()=>{
return Id.getInstance('idcard');
}
}
]);
const childInjector = injector.resolveAndCreateChild([Person]);
const person = injector.get(Person);
console.log(JSON.stringify(person));
const personFromChild = childInjector.get(Person);
console.log(person===personFromChild); //false
}
子注入器當中沒有找到依賴的時候會去父注入器中找
以上就是詳解Angular依賴注入的詳細內容,更多關于Angular的資料請關注腳本之家其它相關文章!
相關文章
Angularjs中ng-repeat-start與ng-repeat-end的用法實例介紹
這篇文章主要給大家介紹了Angularjs中ng-repeat-start與ng-repeat-end的用法,文章開始先進行了簡單的介紹,而后通過完整的實例代碼詳細給大家介紹這兩者的用法,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-12-12
使用AngularJS和PHP的Laravel實現單頁評論的方法
這篇文章主要介紹了使用AngularJS和PHP的Laravel實現單頁評論的方法,本文的示例是前端JavaScript和后端PHP聯(lián)合編程的典范,需要的朋友可以參考下2015-06-06

