記錄遇到的一個迴圈依賴問題

weiewiyi發表於2022-07-12

最近想使用一個service的時候報了迴圈依賴的問題。

官方指導給的呼叫方法很簡單,在建構函式中新增notifyService,然後直接呼叫即可。

export class ThyNotifyBasicExampleComponent implements OnInit {
    constructor(private notifyService: ThyNotifyService) {}

    ngOnInit() {}

    showDefault() {
        this.notifyService.show({
            title: '新增專案成功!'
        });
    }
}

image.png

但是我在使用的時候卻報了notifyService的迴圈依賴。
NG0200: Circular dependency in DI detected for ThyNotifyService
如圖
image.png

image.png


嘗試解決:

上谷歌搜尋後,最開始嘗試了這種方法: 建構函式裡構造的是Injector,
接著在函式給定義的屬性賦值。

private payrollService:PayrollService;
constructor(injector:Injector) {
  setTimeout(() => this.payrollService = injector.get(PayrollService));
}

image.png


在 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屬性
  1. @Injectable 中的providedIn屬性

@Injectable({providedIn:'root'})
export class AService {
」

providedIn: 'root' 告訴 Angular在根注入器中註冊這個服務。

若這種方式註冊,就不用在 @NgModule 裝飾器中寫 providers 。並且在程式碼編譯打包時, 會進行搖樹優化,會移除所有沒在應用中使用過的服務。比較推薦。

  1. @NgModule 中的 providers屬性
@NgModule({
    providers: [
        HeroService,
       // { provide: HeroService, useClass: HeroService }
    ],

若service中沒有在根注入器中注入該服務,若我們想在元件中使用service,就需要使用手動注入service。

注入的識別是通過引數的字元名稱token, 所以
{ provide: HeroService, useClass: HeroService } 的 provide就是我們設定的名稱token, useValue表示使用哪個服務。

若名稱與service名相同,我們也可以簡化,直接使用HeroService。

  1. @Component 後設資料中的 providers屬性
// service.ts
@Injectable() 
 
// component.ts
@Component({
  ...
  selector: 'app-heroes',
  providers: [ HeroService ]
})

這種方式和@NgModule差不多。


由於不知道我引用的外接service是否注入了根注入器,我先假設它沒有注入,於是手動在@NgModule中注入了一下。程式碼如下。


@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    IndexModule,
    LabelRoutingModule,
  ],
  providers: [
    ThyNotifyService
  ]
})

注入之後報錯依舊。
image.png

最後解決方式:

最後嘗試了很多次,
解決方式是在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。

相關文章