AngularJS 4(六)【依賴注入】

風靈使發表於2018-08-24

依賴注入

依賴注入是重要的程式設計模式。 Angular 有自己的依賴注入框架,離開了它,幾乎沒法構建 Angular 應用。 它使用得非常廣泛,以至於幾乎每個人都會把它簡稱為 DI。

從服務開始來了解依賴注入

建立字典服務 – ./src/app/service/dictionary.service.ts

export class DictionayService {
    lan: String = "cn";
}

在根模組依賴注入 – ./scr/app/app.module.ts

import {DictionayService} from './service/dictionary.service.ts'
@NgModule({
    providers: [
        DictionayService 
    ]
})

在根元件使用依賴注入的服務 – ./src/app/app.component.ts

import { Component} from '@angular/core';
import {DictionayService} from './service/dictionary.service.ts'

@Component({
    selector: 'app-root',
    template: `
        <h1>{{dic.lan}}</h1>
        <select [(ngModel)]="dic.lan">
            <option value="cn">cn</option>
            <option value="en">en</option>
        </select>`,
})
export class AppComponent {
    constructor(private dic: DictionayService) {}
}

在根元件使用依賴注入的服務 – ./src/app/student.component.ts

import { Component} from '@angular/core';
import {DictionayService} from './service/dictionary.service.ts'

@Component({
    selector: 'app-root',
    template: `<h1>{{dic.lan}}</h1>`,
})
export class AppComponent {
    constructor(private dic: DictionayService) {}
}

在上面的案例中可以看到當在根元件中更改 DictionayService 的時候,其子元件也同步發生改變。如果在上面案例中不使用依賴注入,而是當普通的類使用,在子元件例項化一個 DictionayService 的例項,會發現當更元件改變的時候,子元件不會發生改變。

所以依賴注入可以理解成一個全域性的物件。在根模組依賴注入的時候就例項化好了一個例項,其它元件在使用的時候都是在使用該例項。

Injectable 裝飾器

在上面的案例中,如果我們想要實現在 DictionayService 發起一個 Ajax 請求,然後把請求的資料在依賴注入後拿來做全域性陣列物件,那程式碼將改成下面這樣

更改字典服務 – ./src/app/service/dictionary.service.ts

import { Http } from '@angular/http';
export class DictionayService {
    lan: String = "cn";
    dataset: Object;
    constructor(http: Http){
        http.get('api').subscribe((res) => {
            this.dataset = res.json();
          });
    }    
}

更改程式碼後將會發生一個錯誤

compiler.es5.js:1694Uncaught Error: Can't resolve all parameters for DicService: (?)

這是因為在依賴注入的時候,沒能將 Http 物件同時依賴注入進來。這個時候就要使用到 Injectable 裝飾器。

import { Http } from '@angular/http';
import { Injectable } from '@angular/core';

@Injectable()
export class DictionayService {
    lan: String = "cn";
    dataset: Object;
    constructor(http: Http){
        http.get('api').subscribe((res) => {
            this.dataset = res.json();
          });
    }    
}

總結

  • 依賴注入可以理解成整個應用的全域性物件
  • 果所建立的服務不依賴於其他物件,是可以不用使用 Injectable 類裝飾器
  • 不過比較推薦的做法不管是否有依賴物件,在建立服務時都使用 Injectable 類裝飾器。

相關文章