最近想使用一個service的時候報了迴圈依賴的問題。
官方指導給的呼叫方法很簡單,在建構函式中新增notifyService
,然後直接呼叫即可。
export class ThyNotifyBasicExampleComponent implements OnInit {
constructor(private notifyService: ThyNotifyService) {}
ngOnInit() {}
showDefault() {
this.notifyService.show({
title: '新增專案成功!'
});
}
}
但是我在使用的時候卻報了notifyService
的迴圈依賴。NG0200: Circular dependency in DI detected for ThyNotifyService
如圖
嘗試解決:
上谷歌搜尋後,最開始嘗試了這種方法: 建構函式裡構造的是Injector,
接著在函式給定義的屬性賦值。
private payrollService:PayrollService;
constructor(injector:Injector) {
setTimeout(() => this.payrollService = injector.get(PayrollService));
}
在 Angular 中 Injector (注入器) 用來管理服務物件的建立和獲取,
Injector 抽象類中定義了一個 get()
抽象方法,該方法用於根據給定的 Token 從注入器中獲取相應的物件,每個Injector 抽象類的子類都必須實現該方法。
雖然不知道為什麼他說這樣做可以解決迴圈依賴問題,但是經過我嘗試之後,很明顯沒有用。
Provide:
根據報錯NO provide xxx, 可以猜測是因為沒有提供某個類
發現自己突然對provide注入忘得差不多了。於是大概講一下
AngularJS文件對provider的定義:
provider是一個帶有$get()方法的物件。injector呼叫$get方法建立一個新的service
在Angular中有很多方式可以將服務類註冊到注入器中:
@Injectable
中的providedIn
屬性@NgModule
中的providers
屬性@Component
中的providers
屬性
- @Injectable 中的providedIn屬性
@Injectable({providedIn:'root'})
export class AService {
」
providedIn: 'root' 告訴 Angular在根注入器中註冊這個服務。
若這種方式註冊,就不用在 @NgModule 裝飾器中寫 providers 。並且在程式碼編譯打包時, 會進行搖樹優化,會移除所有沒在應用中使用過的服務。比較推薦。
- @NgModule 中的 providers屬性
@NgModule({
providers: [
HeroService,
// { provide: HeroService, useClass: HeroService }
],
若service中沒有在根注入器中注入該服務,若我們想在元件中使用service,就需要使用手動注入service。
注入的識別是通過引數的字元名稱token, 所以{ provide: HeroService, useClass: HeroService }
的 provide就是我們設定的名稱token, useValue表示使用哪個服務。
若名稱與service名相同,我們也可以簡化,直接使用HeroService。
- @Component 後設資料中的 providers屬性
// service.ts
@Injectable()
// component.ts
@Component({
...
selector: 'app-heroes',
providers: [ HeroService ]
})
這種方式和@NgModule差不多。
由於不知道我引用的外接service是否注入了根注入器,我先假設它沒有注入,於是手動在@NgModule中注入了一下。程式碼如下。
@NgModule({
declarations: [],
imports: [
CommonModule,
IndexModule,
LabelRoutingModule,
],
providers: [
ThyNotifyService
]
})
注入之後報錯依舊。
最後解決方式:
最後嘗試了很多次,
解決方式是在providers ThyNotifyService的基礎上再引入一個ThyNotifyModule
。如下第7和10行。
1 @NgModule({
2 declarations: [],
3 imports: [
4 CommonModule,
5 IndexModule,
6 LabelRoutingModule,
7 ThyNotifyModule
8 ],
9 providers: [
10 ThyNotifyService
11 ],
})
由於不太清楚這些外接元件庫的實現方式,最後也沒太搞懂為什麼使用ThyNotifyService 需要引入ThyNotifyModule。
官方也沒寫清楚需要引入這個。所以也試了不久。
可能是有些東西依賴ThyNotifyModule。
至於為什麼privide能解決迴圈依賴等問題,由於最近比較忙,等之後有時間再補充。
參考:
https://blog.csdn.net/sllailc...
https://yuyang041060120.githu...
補充
後面發現不是迴圈依賴的問題,只是angular給我們報錯成了迴圈依賴。
原因只是單純地是No provider for ThyQueueStore。
只要提供了ThyQueueStore了就行。
後面我引入ThyNotifyModule, 可能誤打誤撞提供了ThyQueueStore。