[英]Angular 2 - service - dependency injection from another service
我已經在Angular 2中編寫了兩個服務。其中之一是Http
的基本自定義類,其中包含一些自定義功能(目前看來是基本的,但會不斷擴展):
ServerComms.ts
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
@Injectable()
export class ServerComms {
private url = 'myservice.com/service/';
constructor (public http: Http) {
// do nothing
}
get(options) {
var req = http.get('https://' + options.name + url);
if (options.timout) {
req.timeout(options.timeout);
}
return req;
}
}
另一個類TicketService
利用上面的此類,並調用服務中的方法之一。 定義如下:
票務服務
import {Injectable} from 'angular2/core';
import {ServerComms} from './ServerComms';
@Injectable()
export class TicketService {
constructor (private serverComms: ServerComms) {
// do nothing
}
getTickets() {
serverComms.get({
name: 'mycompany',
timeout: 15000
})
.subscribe(data => console.log(data));
}
}
但是,無論何時嘗試此操作,我都會收到以下錯誤:
"No provider for ServerComms! (App -> TicketService -> ServerComms)"
我不理解為什么? 當然,我不需要注入彼此依賴的每項服務嗎? 這會變得很乏味嗎? 這在Angular 1.x中是可以實現的-如何在Angular 2中實現相同的目標?
這是正確的方法嗎?
簡而言之,由於注入器是在組件級別定義的,因此發起呼叫服務的組件必須查看相應的提供者。 第一個(直接調用),但另一個間接調用(由先前的服務調用)。
讓我們取樣。 我有以下應用程序:
組件AppComponent
:在bootstrap
函數中創建Angular2應用程序時提供的應用程序的主要組件
@Component({ selector: 'my-app', template: ` <child></child> `, (...) directives: [ ChildComponent ] }) export class AppComponent { }
組件ChildComponent
:將在AppComponent
組件內使用的AppComponent
組件
@Component({ selector: 'child', template: ` {{data | json}}<br/> <a href="#" (click)="getData()">Get data</a> `, (...) }) export class ChildComponent { constructor(service1:Service1) { this.service1 = service1; } getData() { this.data = this.service1.getData(); return false; } }
兩個服務, Service1
和Service2
: Service1
時使用的ChildComponent
和Service2
通過Service1
@Injectable() export class Service1 { constructor(service2:Service2) { this.service2 = service2; } getData() { return this.service2.getData(); } }
@Injectable() export class Service2 { getData() { return [ { message: 'message1' }, { message: 'message2' } ]; } }
這是所有這些元素及其關系的概述:
Application
|
AppComponent
|
ChildComponent
getData() --- Service1 --- Service2
在這種應用中,我們有三個噴射器:
bootstrap
功能的第二個參數配置的應用程序注入器 providers
屬性配置的AppComponent
注入器。 它可以“看到”在應用程序注入器中定義的元素。 這意味着,如果在此提供程序中找不到提供程序,則會自動在此父注入器中查找。 如果在后者中未找到,將引發“未找到提供程序”錯誤。 ChildComponent
注入器將遵循與AppComponent
相同的規則。 為了注入在組件中執行的注入鏈中涉及的元素,將首先在該注入器中尋找提供程序,然后在AppComponent
者,最后在應用程序中尋找提供者。 這意味着,當嘗試將Service1
注入ChildComponent
構造函數時,Angular2會尋找ChildComponent
注入器,然后是AppComponent
,最后是應用程序。
由於Service2
需要被注入到Service1
,相同分辨率的處理會做到: ChildComponent
注射器, AppComponent
一個應用程序之一。
這意味着可以使用組件的providers
屬性和應用程序注入程序的bootstrap
函數的第二個參數,根據您的需要在每個級別上指定Service1
和Service2
。
這允許共享一組元素的依賴項實例:
因此它非常強大,您可以根據自己的需要和需要自由組織。
這是相應的plunkr,因此您可以使用它: https ://plnkr.co/edit/PsySVcX6OKtD3A9TuAEw?p=preview。
Angular2文檔中的此鏈接可以為您提供幫助: https ://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html。
當然可以。
在Angular2中,有多個注入器。 注入器使用組件的providers
數組進行配置。 當組件具有providers
數組時,將在樹中的該點創建注入器。 當組件,指令和服務需要解決它們之間的依賴關系時,它們會查詢注入器樹以找到它們。 因此,我們需要使用提供程序配置該樹。
從概念上講,我喜歡認為有一個注入器樹覆蓋了組件樹,但它比組件樹稀疏。
同樣,從概念上講,我們必須配置此注入器樹,以便在樹中的適當位置“提供”依賴項。 Angular 2沒有創建單獨的樹,而是重用了組件樹來做到這一點。 因此,即使感覺像我們正在配置對組件樹的依賴關系,我還是認為我正在配置對注入器樹的依賴關系(它恰好覆蓋了組件樹,因此我必須使用組件對其進行配置)。
像泥一樣清澈?
Angular 2擁有注入器樹的原因是允許非單一服務-即能夠在注入器樹中的不同點創建特定服務的多個實例的能力。 如果要使用類似於Angular 1的功能(僅單例服務),請在根組件中提供所有服務。
設計您的應用程序, 然后返回並配置注入器樹(使用組件)。 我就是這么想的。 如果您在另一個項目中重用組件,則很有可能需要更改providers
數組,因為新項目可能需要不同的注入器樹。
好吧,我想您應該在全球范圍內提供兩種服務:
bootstrap(App, [service1, service2]);
或提供給使用它們的組件:
@Component({providers: [service1, service2]})
@Injectable
裝飾器添加必要的元數據來跟蹤依賴關系,但不提供它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.