wake-up-neo.com

Angular 6+: In einem Nicht-Root-Modul wird eine zirkuläre Abhängigkeit verursacht

Ich versuche, einen Auflösungsdienst über das neue Attribut providedIn bereitzustellen.

Dies ist ein Übersetzungs-Resolver, den ich in einem geschützten Modul verwende:

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

import { Observable , pipe } from 'rxjs';
import {map} from "rxjs/operators";

//This is causing: "WARNING in Circular dependency detected:"
import {ProtectedModule} from "../../../protected/protected.module";

import { HttpHandlerService } from '../../http/http-handler.service';

@Injectable({
  providedIn: ProtectedModule //Over here (I need the import for this line)
})
export class TranslationsResolverService {
  constructor(private _httpHandlerService : HttpHandlerService) { }
    resolve(): any {
      //Do Something...
    }
}

Ich habe den Übersetzungsauflösungsdienst im geschützten Routing-Modul deklariert:

import { NgModule }           from '@angular/core';
import {RouterModule, Routes} from '@angular/router';

import {AuthGuard} from "../core/resolvers/auth/auth.guard";
import {TranslationsResolverService} from "./../core/resolvers/translations/translations-resolver.service";

const routes: Routes = [
  {
    path : 'app' ,
    component: ProtectedComponent,
    resolve : {
      translations : TranslationsResolverService // <---- Over here - i can't remove that of course
    },
    canActivate: [AuthGuard],
    ]
  }
];


@NgModule({
  imports : [RouterModule.forChild(routes)],
  exports : [RouterModule]
})
export class ProtectedRoutingModule { }

Da ich den protected.module in dem translations-resolver.service.tsm es im providedIn-Attribut zu verwenden Ich erhalte eine Warnung in der Zirkelabhängigkeit:

path/to/translations-resolver.service.ts -> 

protected/protected.module.ts ->

protected/protected-routing.module.ts -> 

path to translations-resolver.service.ts

Der 2. Pfad (protected/protected.module.ts) wird aufgrund des Attributs providedIn hinzugefügt.

Ich kann das beheben, indem ich translationsResolver als NgModule provider (im Anbieter-Array), aber ich bevorzuge es, ein injectable -Anbieter zu sein.

Irgendwelche Vorschläge zur Lösung dieses Problems?

22
Rotemya

Dies ist kein Angular Abhängigkeitsproblem.

Der Zirkelverweis wird vom TypeScript-Compiler generiert, wenn versucht wird, den Zirkel Importe aufzulösen.

Erste Lösung

Erstellen Sie ein neues Modul mit dem Namen ProtectedResolversModule und verwenden Sie providedIn: ProtectedResolversModule und bewegen Sie die Resolver dorthin.

Jetzt können Sie dieses Modul in ProtectedModule importieren und erhalten beim Laden von ProtectedRoutingModule keinen zirkulären Abhängigkeitsfehler.

Zweite Lösung

Verwenden Sie das Array providers von ProtectedModule.

9
Reactgular

Ich bin auf dasselbe Problem gestoßen. Es hat sich herausgestellt, dass die Lösung "Mach es nicht" ist, wie in diesem Thread von einem der Angular Jungs erklärt: https://github.com/angular/angular- cli/issues/10170 # issuecomment-380673276

Es läuft darauf hinaus, dass Services einfacher per Tree-Shake zu verwalten sind, wenn sie vom Root-Modul bereitgestellt werden.

Ich bin so enttäuscht wie du.

13
DarkNeuron

Ich denke, Angular hat die providedIn -Syntax ein wenig durcheinander gebracht. Es scheint eine Menge Leute verwirrt zu haben. ZB sehen Sie diese beiden Github-Threads:

Die providedIn -Syntax scheint zwei Hauptvorteile zu haben :

  1. Es unterstützt das Tree-Shaking nicht verwendeter Dienste
  2. providedIn: 'root' Stellt sicher, dass Sie immer nur eine Instanz des Dienstes erhalten

Aber Sie brauchen (1) nur dann wirklich, wenn Sie eine Bibliothek schreiben, und nicht eine Anwendung Sie können mehrere Dienstinstanzen (2) vermeiden, indem Sie nur sicherstellen, dass Sie das Dienstmodul nicht mehr als einmal importieren.

Die Probleme mit der providedIn Syntax sind:

  1. providedIn: 'root' Unterbricht die Verbindung zwischen dem Dienst und dem Modul, in dem er "lebt" (oder "mit") - weil der Dienst nichts über das Modul weiß und das Modul nichts über den Dienst weiß. Dies bedeutet, dass der Service nicht mehr wirklich zu diesem Modul "gehört" und nur noch mit den entsprechenden Referenzen gebündelt wird. Dies bedeutet wiederum, dass es nun Sache des Service-Verbrauchers ist , sicherzustellen, dass die injizierbaren Abhängigkeiten des Service (falls vorhanden) verfügbar sind, bevor er verwendet wird, was verwirrend und recht ist kontraintuitiv.
  2. Das oben beschriebene Zirkelreferenzproblem. Es ist tatsächlich nicht möglich , dass - über diese Syntax - die Verbindung zwischen dem Dienst und seinem Modul erhalten bleibt , wenn der Dienst tatsächlich von irgendeinem verwendet wird Komponenten innerhalb desselben Moduls .

Dies widerspricht der offiziellen Angular Anleitung, aber mein Rat wäre: Verwenden Sie providedIn nur, wenn Sie einen Dritten schreiben Bibliothek, die ein Tree-Shaking erfordert - verwenden Sie stattdessen die alte (nicht veraltete) providers -Syntax auf dem Modul, dh:

@NgModule({ providers: [MyService], })

4
Dan King

Überprüfen Sie forwardRef () Funktion von Winkel/Kern. Hiermit kann auf Referenzen verwiesen werden, die noch nicht definiert sind.

import {MyService} from './service';

constructor(@Inject(forwardRef(() => MyService)) public myService: MyService) {
}
0
Ozgur